Skip to content

Syntax for explicit tuple literal type #48052

Open
@graphemecluster

Description

@graphemecluster

Suggestion

Though closely related to #10195 and #16656, I am opening this issue because the proposed syntax, purpose and demonstration are different.

Motivation

Previously I wrote a library that manipulates nested arrays:

import NDArray from "ndarray-methods";

NDArray.buildShape([2, 3], 0) // [[0, 0, 0], [0, 0, 0]]
// Works like Python’s numpy.zeros()

But without tuple its type is being inferred as NDArray<number>, of which NDArray is defined as

type NDArray<T> = (T | NDArray<T>)[]

The Problem

I know there are at least 3 ways to cast it as a tuple:

/* 1 */ NDArray.buildShape([2, 3] as const, 0)            // constant tuple
/* 2 */ NDArray.buildShape([2, 3] as [number, number], 0) // number tuple
/* 3 */ NDArray.buildShape(tuple(2, 3), 0)                // utility function

of which the tuple function is defined as

function tuple<T extends unknown[]>(...args: T) { return args; }

In these 3 cases, the program correctly infers the type of the results as number[][].

But these 3 ways all have their problems:

For 1, it is not necessary to make the numbers constants.

For 2, we will have to write number, many times for higher-dimensional arrays (I know we can use a utility type, but I don’t think it’s desirable).

For 3, there are considerable runtime effects and it might cause serious performance problems, especially when it is transpiled down to something like

function tuple() {
  for (var a = [], i = 0; i < arguments.length; i++) a.push(arguments[i]);
  return a;
}

Also, in a module-based application, this utility function will have to be defined or imported before using, which pollutes the namespace.

Most importantly, for 1 and 2, we are using the as keywords, which is not favorable for TypeScript codes in general (and ESLint gets angry too).

I also know the existence of the Record & Tuple Proposal, but since there will be compatibility problems in the near future, and people might not want to refactor the existing codes, the current tuple-like array will still be used by a significant amount of projects.

Solution

In my opinion, a syntax without as like tuple [2, 3] should be created, or we should at least provide a way to let TypeScript infer a literal array as tuple for a certain function parameter.

Prior Use

The tuple utility function is included in many repositories, and even in the release note:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions