Repository navigation
Tuple type #50838
Copy link
Copy link
Closed as not planned
Labels
DeclinedThe issue was declined as something which matches the TypeScript visionThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScriptAn idea for TypeScript
Description
The Tuple type
We want to create a type called Strings50 that is a tuple with 50 strings.
type Strings50 = [
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string,
string
];Welp, that's one way of doing it. Or, you could use this utility type I'm proposing:
type Tuple<T, N, R extends T[] = []> = R['length'] extends N ? R : Tuple<T, N, [...R, T]>;With this recursive type, the abomination above can be refactored to this:
type Strings50 = Tuple<string, 50>;Use case example
We have a function that takes in an array and a chunk size, then returns that same array chunked out:
const chunkArray = <T extends unknown>(arr: T[], size: number) => {
const copy = [...arr];
return [...Array(Math.ceil(arr.length / size))].map(() => copy.splice(0, size));
};
// x looks like -> [['hello', 'world'], ['foo', 'bar'], ['fizz', 'buzz']];
const x = chunkArray(['hello', 'world', 'foo', 'bar', 'fizz', 'buzz'], 2);This is fine. The function returns T[][], and x is a string[][]. But, since for our use case, we intend to use non-dynamic chunk sizes when calling this function, we can make the return type more accurate:
const chunkArray = <T extends unknown, N extends number>(arr: T[], size: N) => {
const copy = [...arr];
return [...Array(Math.ceil(arr.length / size))].map(() => copy.splice(0, size)) as Tuple<T, N>[];
};
const x = chunkArray(['hello', 'world', 'foo', 'bar', 'fizz', 'buzz'], 2);
const y = chunkArray(['hello', 'world', 'foo', 'bar', 'fizz', 'buzz'], 3);Instead of having the type string[][], x now has a type of [string, string][], and y of course has a type of [string, string, string][].
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
DeclinedThe issue was declined as something which matches the TypeScript visionThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScriptAn idea for TypeScript
Activity
MartinJohns commentedon Sep 18, 2022
See #39522 (comment):
Related: #47874
Repeat to Tuple, 설명 참조