Typescript: Automatically type inference for tuple arrays

Created on 14 Jul 2019  路  8Comments  路  Source: microsoft/TypeScript

Search Terms

automatically type inference for tuple arrays

Suggestion

Currently, TypeScript is not able to automatically infer the type of an array of tuples.

For example:

const data = [
  ['name', 'Luiz Felipe', true],
  ['age', 16, false]
];

In the above example, TypeScript will infer the type of the data variable as:

(string | boolean)[]

But I think that it should have inferred to:

[string, string, boolean][]

I know that I could have defined the types explicitly in the variable declaration, but I suggest that TypeScript implements this automatic inference system in tuple arrays.

Use Cases

This lack of tuple arrays type inference really annoys me when I need to do something like that:

[
  ['accessToken', tokens.accessToken, ms('15m')],
  ['refreshToken', tokens.refreshToken, ms('90 days')]
].forEach(([key, val, maxAge]) => res.cookie(key, val, { maxAge }));

Because key, val and maxAge are incorrectly typed as string | number.

Checklist

My suggestion meets these guidelines:

  • [ ] ? This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [x] This wouldn't change the runtime behavior of existing JavaScript code
  • [x] This could be implemented without emitting different JS based on the types of the expressions
  • [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [x] This feature would agree with the rest of TypeScript's Design Goals.
Declined Suggestion

Most helpful comment

as const?

All 8 comments

as const?

This wouldn't be a breaking change in existing TypeScript/JavaScript code

It absolutely would break tons of existing TypeScript code.

I don't know if this is related, but I have this example:
image

Although this might very well be an issue with Jest.

Property expectedIcon does not exist on type string

There's already as const; for any given value there's an infinite number of correct types that could be inferred which satisfy those values but it's impossible to know which you intended. The existing options (as const or heterogeneous arrays) are located on two reasonable extremes and it's probably not possible to introduce more in-between types in a way that's more ergonomic than the extant ways of adding type annotations.

I see... Thanks for the feedback, guys! :)

@lffg I think that in these cases there is room for some helper functions to make it clear what the intent of the code is. Like Ryan said, there are an infinite number of ways to type that array, but if we want a tuple array this function would do that:

const data = tupleArray(
  ['name', 'Luiz Felipe', true],
  ['age', 16, false]
);
data .forEach(([p, v, e]) => {
    // p is string
    // v is number | string
    // e is boolean
});

function tupleArray<T extends  Array<[any] | any[]>>(...a: T): T[number][] {
    return a;
}

Or if we want literal types:

const data = tupleLiteralArray(
  ['name', 'Luiz Felipe', true],
  ['age', 16, false]
) // (["name", "Luiz Felipe", true] | ["age", 16, false])[]

data.forEach(([p, v, e]) => {
    // p 'name' | 'age'
    // v 'Luiz Felipe' | 16
    // e: boolean

});

function tupleLiteralArray<T extends  Array<[V] | V[]>, V extends string | number | boolean | null | undefined | object>(...a: T): T[number][] {
    return a;
}

as const is always an option, but the applying it to the whole array makes the whole array a readonly tuple (which is not always intended) and applying it to each tuple in the arrays seems tedious and error prone. Using a function makes intent clear (the name you give can suggest the type being inferred) and potentially removes the as const assertion from a lot of places.

Property expectedIcon does not exist on type string

I know, but string is the first param, it should know I'm using the second param.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CyrusNajmabadi picture CyrusNajmabadi  路  3Comments

weswigham picture weswigham  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments

zhuravlikjb picture zhuravlikjb  路  3Comments

dlaberge picture dlaberge  路  3Comments