Skip to content

Tuple with element after spread not assignable to tuple with rest elements #33573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
AnyhowStep opened this issue Sep 24, 2019 · 3 comments
Closed
Labels
Bug A bug in TypeScript
Milestone

Comments

@AnyhowStep
Copy link
Contributor

AnyhowStep commented Sep 24, 2019

TypeScript Version: 3.5.1, 3.6.3, Nightly (2019-09-24)

Search Terms:

Tuple, spread, assignability

Code

declare const src : [number, ...number[]];

const [head, ...tail] = src;

//Expected: OK
//Actual  : OK
const dst0 : [number, ...number[]] = [head, ...tail];

//Expected: OK
//Actual  : Error
//Property '0' is missing in type 'number[]' but required in type '[number, ...number[]]'.
const dst1 : [number, ...number[]] = [head, ...tail, 1337];

Expected behavior:

Assignment to dst1 should succeed.

It should succeed because head is number and ...tail, 1337 should correspond to ...number[]

Actual behavior:

Assignment to dst1 fails.

Playground Link:

3.5.1 Playground

Related Issues:

Possibly this,
#29248

It mentions spread arguments, and an extra argument at the end causes TS to not realize there are the right number of arguments.
However, this repro just has tuples not being assignable to other tuples.

@AnyhowStep
Copy link
Contributor Author

AnyhowStep commented Sep 24, 2019

This is my current workaround,

const src : readonly [number, ...number[]] = [1,2,3,4,5] as const;

interface ReadonlyArray<T> {
    concat (
        this : readonly [T, ...T[]],
        ...items: (T | ConcatArray<T>)[]
    ) : ([T, ...T[]])
}

//Expected: OK
//Actual  : OK
const dst2 : [number, ...number[]] = src.concat(1337);

console.log(src);
console.log(dst2);

3.5.1 Playground


If anyone is using this for a tuple-of-arrays, you'll need,

const src : readonly [[number, number], ...[number, number][]] = [[1,2], [3,4]];

interface ReadonlyArray<T> {
    concat (
        this : readonly [T, ...T[]],
        ...items: (T | ConcatArray<T>)[]
    ) : ([T, ...T[]])
}
interface Array<T> {
    concat (
        this : readonly [T, ...T[]],
        ...items: (T | ConcatArray<T>)[]
    ) : ([T, ...T[]])
}

//Expected: OK
//Actual  : OK
const dst2 : readonly [[number, number], ...[number, number][]] = src.concat([5,6]);

console.log(src);
console.log(dst2);

3.5.1 Playground


Should the above overloads for concat be added to the lib.d.ts files?

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Sep 25, 2019
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.8.0 milestone Sep 25, 2019
@Andarist
Copy link
Contributor

@RyanCavanaugh this works OK today, the issue can be closed

@jakebailey
Copy link
Member

Just looking at old issues; this was fixed in #39094.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants