tuple type rest spread typescript
I'd like to be able to write tuple types using the spread operator. For example:
type Foo = [string, ...number[]]; // first elt must be string, rest must be numbers
Currently, this produces an error at the ellipsis: "Type expected".
Here is a question asking much the same thing on Stack Overflow: https://stackoverflow.com/questions/44934541/how-to-use-the-spread-operator-in-a-typescript-tuple
It seems related to https://github.com/Microsoft/TypeScript/issues/10727, but that issue focuses on Object rest/spread, whereas this is specifically about tuples.
Typed tuples are part of the existing language. So it seems natural that one should be able to type rest arguments .
For example, if you want to represent a syntax tree, you might want to write:
type FunCall = ['FUNCALL', Symbol, ...Expression[]]; // error in 2.9.1 :(
type Symbol = string;
type Expression = FunCall | Scalar;
type Scalar = number | string | null;
But this isn't allowed in Typescript 2.9.1.
type Foo = [string, ...number[]];
const f1: Foo = ["str", 2, 3, 4]; // should pass
const f2: Foo = ["str", "2", 3, 4]; // should fail:
// "Type '(string | number)[]' is not assignable to type 'number[]'.
const f2: Foo = ["str", 2, "3", 4]; // should fail:
// "Type '(number | string)[]' is not assignable to type 'number[]'.
const f1: Foo = [1, 2, 3, 4]; // should fail:
// "Type 'number' is not assignable to type 'string'.
My suggestion meets these guidelines:
I think is already in progress in #24897 (see Open-ended tuple types block).
@ahejlsberg can answer better.
Ah, thanks for the pointer, @j-oliveras.
@ahejlsberg, #24897 seems to deal with rest arguments to functions, whereas this deals with definition of tuple types with the rest operator. Does it makes sense to include tuple types in that issue?
Here's another issue which focuses on rest in function calls: https://github.com/Microsoft/TypeScript/issues/17934
And a work in progress which uses generics for defining tuple types: https://github.com/Microsoft/TypeScript/pull/17884
Should be implemented by #24897. the syntax will be [number, string*]
UPDATE: final syntax will be [number, ...string[]].
Most helpful comment
UPDATE: final syntax will be
[number, ...string[]].