Skip to content
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

Wrong function return type inference (union type parameter) #35106

Closed
sheerlox opened this issue Nov 14, 2019 · 4 comments
Closed

Wrong function return type inference (union type parameter) #35106

sheerlox opened this issue Nov 14, 2019 · 4 comments

Comments

@sheerlox
Copy link

TypeScript Version: 3.8.0-dev.20191114

Search Terms: Wrong union type parameter function result type inference

Code

interface ITestRequired {
    key: string
    ignoredKey: string
}

interface ITestOptional {
    key?: string
    ignoredKey?: string
}

export const unwrapTestObject = ({ key }: ITestRequired | ITestOptional) => ({ key })

// testObj is of ITestRequired type
const testObj: ITestRequired = {
    key: 'test',
    ignoredKey: 'test'
}

const testFilter = unwrapTestObject(testObj)

// testFilter.key should always be a string here, but instead we get
// testFilter.key is possibly 'undefined'.
console.log(testFilter.key.substring(0, 2))

Expected behavior:
Output type should be inferred from input type even when using Union types (because it is specified in the parameter type).

Actual behavior:
Parameter type is totally ignored.

Playground Link

Related Issues:
Did not find anything similar.

@AnyhowStep
Copy link
Contributor

Are you looking for generic functions?

@sheerlox
Copy link
Author

@AnyhowStep like so ?

export const unwrapTestObject = <T>({ key }: T) => ({ key })

indeed it seems to do the job, but I'm getting Property 'key' does not exist on type 'unknown'. as I'm trying to destructure the parameter (seems like TS generics and destructuring are not friends from what I could find in the issues).

Playground Link

@jcalz
Copy link
Contributor

jcalz commented Nov 14, 2019

More like

const unwrapTestObject = <T extends ITestOptional>({ key }: T): Pick<T, "key"> => ({ key })

The compiler is working as intended (the compiler doesn't distribute control flow analysis over union types); you might consider closing this issue. Good luck!

@sheerlox
Copy link
Author

sheerlox commented Nov 14, 2019

That's a bit complicated but thanks it's working !
I was simply hoping for something more "generic" ^^

Because I simplified this for the example, but I have to do this with objects of 50 keys or more.

So i need to put them all in the Pick, which looks like shit once it's done.

Sorry I opened a bug report for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants