Skip to content

Conditional return type wrong on function, but correct on caller #49897

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
metehus opened this issue Jul 14, 2022 · 3 comments
Closed

Conditional return type wrong on function, but correct on caller #49897

metehus opened this issue Jul 14, 2022 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@metehus
Copy link

metehus commented Jul 14, 2022

Bug Report

I'm working on a function, that should return ResponseA when a parameter is true, or ResponseB otherwise. The return on the execution works fine, but when returning it inside the function, there's a type error, needing to use as any to fix it

🔎 Search Terms

I've tried to search about conditional returns by functions, but didn't find any regarding this issue

🕗 Version & Regression Information

Tried on 4.7.4 and the nightly version

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about conditional type

⏯ Playground Link

Playground link with relevant code

💻 Code

interface ResponseA {
    fooBar: string
}

interface ResponseB {
    specialNumber: number
}


type ShouldGetFirst<R extends [unknown, unknown], SHOULD extends boolean>
    = SHOULD extends true ? R[0] : R[1]


function getInfo<B extends boolean>(format: B): ShouldGetFirst<[ResponseA, ResponseB], B> {
    if (format) {
        return {
            fooBar: 'hello world' // Type '{ fooBar: string; }' is not assignable to type 'ShouldGetFirst<[ResponseA, ResponseB], B>'
        }
    } else {
        return {
            specialNumber: 42 // Type '{ specialNumber: number; }' is not assignable to type 'ShouldGetFirst<[ResponseA, ResponseB], B>'
        }
    }
}

const a = getInfo(true) // a is ResponseA
const b = getInfo(false) // b is ResponseB

🙁 Actual behavior

The return statements are returning an not assignable error, even that, when executing the function(as seen on the end), the response types are correct.

🙂 Expected behavior

The problem should not exist, so it's not needed to use as any

@MartinJohns
Copy link
Contributor

Resolving of conditional types involving unbound generic type arguments is deferred. At that point the compiler doesn't know what ShouldGetFirst<[ResponseA, ResponseB], B> resolves to, because the compiler doesn't know what type B is. Constraints are not taken into consideration. Same as #48243.

When actually calling the function the type argument is not unbound anymore, so the conditional type can be resolved.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jul 14, 2022
@RyanCavanaugh
Copy link
Member

Also #33014

@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants