Tuple with fixed length
Asked Answered
A

3

9

Typescript in tuple allows to add extra elements with any of types used before, but I would like to limit the length. I've tried with & { length: 2 }, but it didn't helped:

declare var a: [string, number] & { length: 2 };

a[0] = "1"
a[1] = 2;
a[2] = "3";
a[3] = 4;

Assignments for [2] and [3] don't produce error. How can I specify corresponding type?

Allover answered 24/9, 2018 at 18:16 Comment(4)
Some solutions here : #41140263Kimes
@colxi, actually there is no such problem starting from version 3.1.Allover
Tuples do not prevent you from adding/deleting keys after Array initialization, but there are solutions to implement a safe FixedLengthArray type signaturesKimes
@colxi, yep, I've understood your answer to that question.Allover
A
8

Use type never for array tail:

declare var a: [string, number, ...never[]];

and you'll get

Type '"3"' is not assignable to type 'never'.

Type '4' is not assignable to type 'never'.

Allover answered 24/9, 2018 at 18:16 Comment(0)
P
3

If you are using Typescript 4.1 or newer, you can utilize Recursive conditional types to create tuple types with flexible length:

type TupleOf<T, N extends number> = N extends N ? number extends N ? T[] : _TupleOf<T, N, []> : never;
type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>;

which allows you to easily specify the value type and length of your tuple

type T1 = TupleOf<string, 3>;

Then such tuple would compile

const tuple: T1 = ['one', 'two', 'three'];

whereas this one wouldn't

const tuple: T1 = ['one', 'two', 'three', 'four'];
TS2322: Source has 4 element(s) but target allows only 3

The downside is of course that you can't easily specify different types in the tuple, so this approach is rather suitable for single-typed tuples.

Polis answered 7/3, 2022 at 9:36 Comment(0)
A
0

If you are using Typescript 3.1 or newer you don't need to add special limitations to tuples:

declare var a: [string, number];

You may notice that code

declare var a: [string, number];

a[0] = "1"
a[1] = 2;
a[2] = "3";
a[3] = 4;

compiles in 3.0.1 but doesn't compile in 3.1.6 with messages

Index '2' is out-of-bounds in tuple of length 2.
Index '3' is out-of-bounds in tuple of length 2.

Allover answered 21/2, 2020 at 15:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.