Syntax for explicit tuple literal type
See original GitHub issueSuggestion
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:
- Created 2 years ago
- Reactions:5
- Comments:5 (2 by maintainers)
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-1248241872Proposal: maybe a new
as tuple
cast, as a twist onas const
that only changes an array to a tuple and doesn’t applyreadonly
anywhere?Blatantly copying @chaance’s suggestion in https://twitter.com/chancethedev/status/1527695898318458880. 🙌