leszczu450
leszczu450

Reputation: 283

No accurate type for elements in nested arrays

Given this code:

[['one',1], ['two',2], ['three',3], ['four',4]]
  .forEach(([text, num]) => text + num);

the most correct type I'm getting from TS is string | number. Can we do it better? What does TS can not infer the types more accurately?

Upvotes: 0

Views: 72

Answers (1)

Maciej Sikora
Maciej Sikora

Reputation: 20162

TypeScript out box takes very loose assumption about the type. To define clearly that this array has this shape not by example, but always, we can or specify the type explicitly, or do the shortcut by using as const

([['one', 1], ['two', 2], ['three', 3], ['four', 4]] as const)
.forEach(([text, num]) => text + num);

Now TS is inferencing very strict, that every element is a tuple, and even specify it to the union of possible values.

Eventually you can assert to less specified type like array of tuples [string, number][].

([['one', 1], ['two', 2], ['three', 3], ['four', 4]] as [string, number][])
.forEach(([text, num]) => text + num);

The most explicit way would be to just typed that. I would prefer that:

type StrNumber = [string, number];
const arr: StrNumber[] = [['one', 1], ['two', 2], ['three', 3], ['four', 4]];
arr.forEach(([text, num]) => text + num);

Edit One thing to add, as there was additional question in the comment. Why such does not work:

[['one', 1], ['two', 2], ['three', 3], ['four', 4]]
    .forEach(([text, num]: [string, number]) => text + num) // error

It does not because TS is checking types from top to bottom. It means that type declaration below has to match type declaration above. If you are saying that your predicate has an argument of [string, number] it means that it can work only on such, but unfortunetly TS sees the above array elements and inference them as string | number)[]. It is clear that function which works on [string, number] cannot work on wider type string | number)[]. You cannot derive above type from bottom, you can derive from top to bottom.

Upvotes: 3

Related Questions