Home > Enterprise >  Infer type from tuple contents
Infer type from tuple contents

Time:05-21

Say I have a generic tuple type:

type MyTuple<A, B> = [A, B]

The following works, because I give it the generic types:

const thing2: MyTuple<number, string> = [20, 'hello']

I want to use it like this, but it gives an error:

const thing1: MyTuple = [20, 'hello'] // -> Generic type 'MyTuple' requires 2 type argument(s).

I don't understand why it needs the generic args in this instance - I rarely have to specify the generic type when using map for example.

Code here.

CodePudding user response:

You defined a generic type without default values.

MyTuple has no meaning without its 2 generic parameter.


type MyTuple<A = number, B = string> = [A, B]

const thing1: MyTuple = [20, 'hello']

This example works for example, but it's probably not what you were loooking for.

CodePudding user response:

Type parameters for generic types like MyTuple<A, B> do not get inferred by the compiler.

There was a request for this ability in microsoft/TypeScript#30120, which was closed as a duplicate of the longstanding open feature request at microsoft/TypeScript#26242. Maybe in some future version of TypeScript you could write const thing1: MyTuple<infer, infer> = [20, 'hello'] and it would work how you want. But for now (TS4.7 and below) this isn't possible.


On the other hand, type parameters for generic functions do get inferred by the compiler when you call them (like the map() method on arrays, for example). This means you can work around your issue by creating a generic helper identity function:

type MyTuple<A, B> = [A, B]
const myTuple = <A, B>(t: MyTuple<A, B>) => t;

And instead of writing const x: MyTuple<XXX,YYY> = y, you write const x = myTuple(y):

const thing1 = myTuple([20, 'hello']);
// const thing1: MyTuple<number, string>

Now thing1 has been inferred as being type MyTuple<number, string> as desired. It might not be optimal to have this no-op function, but it's the closest we can get to what you want for now.

Playground link to code

  • Related