Update: These checks are meant for compile time, not at runtime. In my example, the failed cases are all caught at compile time, and I'm expecting similar behaviour for the other should-fail cases.
Suppose I'm writing a table-like class where I want all members of the class to be arrays of the same length, something like:
class MyClass {
tableHead: string[3]; // expect to be a 3 element array of strings
tableCells: number[3]; // expect to be a 3 element array of numbers
}
The closest solution I've found so far is:
class MyClass {
tableHead: [string, string, string];
tableCells: [number, number, number];
}
let bar = new MyClass();
bar.tableHead = ['a', 'b', 'c']; // pass
bar.tableHead = ['a', 'b']; // fail
bar.tableHead = ['a', 'b', 1]; // fail
// BUT these also pass, which are expected to fail at compile time
bar.tableHead = ['a', 'b', 'c', 'd', 'e']; // pass
bar.push('d'); // pass
bar.push('e'); // pass
Any better ideas?
Update 2: From version 3.4, what the OP asked for is now fully possible with a succinct syntax (Playground link):
class MyClass {
tableHead: readonly [string, string, string]
tableCells: readonly [number, number, number]
}
Update 1: From version 2.7, TypeScript can now distinguish between lists of different sizes.
I don't think it's possible to type-check the length of a tuple. Here's the opinion of TypeScript's author on this subject.
I'd argue that what you're asking for is not necessary. Suppose you define this type
type StringTriplet = [string, string, string]
and define a variable of that type:
const a: StringTriplet = ['a', 'b', 'c']
You can't get more variables out of that triplet e.g.
const [one, two, three, four] = a;
will give an error whereas this doesn't as expected:
const [one, two, three] = a;
The only situation where I think the lack of ability to constrain the length becomes a problem is e.g. when you map
over the triplet
const result = a.map(/* some pure function */)
and expect that result
have 3 elements when in fact it can have more than 3. However, in this case, you are treating a
as a collection instead of a tuple anyway so that's not a correct use case for the tuple syntax.