Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tuple type #50838

Closed
mstephen19 opened this issue Sep 18, 2022 · 1 comment
Closed

Tuple type #50838

mstephen19 opened this issue Sep 18, 2022 · 1 comment
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript

Comments

@mstephen19
Copy link

mstephen19 commented Sep 18, 2022

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][].

@MartinJohns
Copy link
Contributor

MartinJohns commented Sep 18, 2022

See #39522 (comment):

We've opted to not include utility type aliases in the lib unless they're required for declaration emit purposes.

Related: #47874

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Declined The issue was declined as something which matches the TypeScript vision labels Sep 20, 2022
@RyanCavanaugh RyanCavanaugh closed this as not planned Won't fix, can't repro, duplicate, stale Sep 20, 2022
WolfgangKurz added a commit to WolfgangKurz/LastOriginWiki that referenced this issue Jan 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants