question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Syntax for explicit tuple literal type

See original GitHub issue

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:

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:5
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
nicojscommented, May 28, 2022

We might not want to use the word tuple as we might want to reserve that for JS native tuples as described in https://github.com/microsoft/TypeScript/issues/49243#issue-1248241872

2reactions
JoshuaKGoldbergcommented, May 28, 2022

Proposal: maybe a new as tuple cast, as a twist on as const that only changes an array to a tuple and doesn’t apply readonly anywhere?

// Proposed:
["hello", 123] as tuple; // Type: ["hello", 123];

// Existing alternatives:
["hello", 123]; // Type: (string, number)[]
["hello", 123] as readonly; // Type: readonly ["hello", 123];
["hello", 123] as [string, number]; // Type: [string, number]
["hello", 123] as ["hello", 123]; // Type: ["hello", 123]

Blatantly copying @chaance’s suggestion in https://twitter.com/chancethedev/status/1527695898318458880. 🙌

Read more comments on GitHub >

github_iconTop Results From Across the Web

Tuple types - C# reference - Microsoft Learn
Use cases of tuples · Tuple field names · Tuple assignment and deconstruction · Tuple equality · Tuples as out parameters · Tuples...
Read more >
Documentation - TypeScript 4.0
The first change is that spreads in tuple type syntax can now be generic. ... an explicit type annotation along with a definite...
Read more >
Tuple Types - Elements Docs
Tuples provide a more lightweight way to group related values without the need of declaring, for example, an explicit Record type. A tuple...
Read more >
Crazy, Powerful TypeScript Tuple Types | by Eamonn Boyle
Be careful how you define it though - we can't make use of type inference as the syntax for a tuple literal is...
Read more >
Tuple types - The Rust Reference
Tuple types are a family of structural types for heterogeneous lists of other types. The syntax for a tuple type is a parenthesized,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found