Update: These checks are meant for compile time, not at runtime. In my example, the failed cases are all caught at compile
From Typescript: Can I define an n-length tuple type?, programmatically, with dynamic length:
type Tuple<TItem, TLength extends number> = [TItem, ...TItem[]] & { length: TLength };
type Tuple9<T> = Tuple<T, 9>;
Here is a simple example of a class to control the length of its internal array. It isn't fool-proof (when getting/setting you may want to consider whether you are shallow/deep cloning etc:
https://jsfiddle.net/904d9jhc/
class ControlledArray {
constructor(num) {
this.a = Array(num).fill(0); // Creates new array and fills it with zeros
}
set(arr) {
if (!(arr instanceof Array) || arr.length != this.a.length) {
return false;
}
this.a = arr.slice();
return true;
}
get() {
return this.a.slice();
}
}
$( document ).ready(function($) {
var m = new ControlledArray(3);
alert(m.set('vera')); // fail
alert(m.set(['vera', 'chuck', 'dave'])); // pass
alert(m.get()); // gets copy of controlled array
});
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.