Skip to content

Tuple type #50838

Closed as not planned
Closed as not planned

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

Activity

  1. MartinJohns commented on Sep 18, 2022

    @MartinJohns
    Contributor

    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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions