You can use the tuple()
function in tuple.ts
to infer tuple types in TypeScript and cut down on the need to repeat yourself. Without tuple()
, declaring a constant of a tuple type looks like this:
const daysOfTheWeek: ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"] =
["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
You can't do this:
const daysOfTheWeek = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
// right value, wrong type
because TypeScript would infer the type of daysOfTheWeek
to be a plain array of string
values.
And you can't do this:
const daysOfTheWeek: ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
// right type, wrong value
because then the variable daysOfTheWeek
would not be defined at runtime.
Enter tuple()
:
import { tuple } from './tuple'; // or wherever you put your libraries
const daysOfTheWeek =
tuple("sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"); // right type, right value
If you inspect the type of daysOfTheWeek
, it will be the desired tuple type ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"]
, and has the correct value at runtime.
Note that the inferred tuple type will be as narrow as it can, interpreting any string
, number
, or boolean
literal element as the
corresponding literal type:
const narrow = tuple("a", 1, true); // inferred as type ["a", 1, true]
If you want to widen any of them, you can do type assertions:
const wider = tuple("a" as string, 1 as 0 | 1 | 2, true as boolean | undefined)
// inferred as [string, 0 | 1 | 2, boolean | undefined]
Also note that the library only supports tuples of length up to twelve; you can add more overloads at the top if you need them.
I have a slightly modified version which makes the tuple elements readonly: https://gist.github.com/seanf/b056a40a7256efee10f53c82e490b5b3
Honestly, it doesn't make much difference if you're making a tuple of literals, because the compiler won't let you assign a different value to the tuple, but it bothered me slightly...
I got the syntax I needed from, who else, @jcalz: microsoft/TypeScript#17563 (comment) Cheers mate!