Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Conditional generic works differently when passed generic function parameter than when directly passed type

I’m trying to make a utility function which will take either a tuple or an array and return whichever it took. I’ve constructed a generic type which understands whether it is passed a tuple or an array, but when I try to use the generic in my utility function, the generic doesn’t detect the tuple:

type Foo = [number, number]

type MaybeFoo<T> = T extends Foo ? Foo : number[]

const bar = [1, 1, 1, 2]
const baz: Foo = [1, 1]

type WasntFoo = MaybeFoo<typeof bar> // WasntFoo is number[], which is what I want
type WasFoo = MaybeFoo<typeof baz> // WasFoo is [number, number], which is what I want

const utilityFunction = <T,>(arr: MaybeFoo<T>): MaybeFoo<T> => arr // in real life this does something to each el of arr but doesn't change the type

const r1 = utilityFunction(bar)
const r2 = utilityFunction(baz) // r2 is number[], when I want [number, number]

This is in TypeScript 4.8.4, playground here

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

This is because the TypeScript compiler can not correctly infer T in your function call. In this case the compiler defaults to unknown and as unknown does not extend Foo the type will be evaluated as number[]. If you add a typing to your function call it works as expected:

const r2 = utilityFunction<Foo>(baz)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading