Skip to content

Spread operator results in incorrect types when used with tuplesΒ #50875

@Zamiell

Description

@Zamiell

Bug Report

πŸ”Ž Search Terms

generic spread operator tuple tuples

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ.

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

// ----------------
// PART 1 - CORRECT
// ----------------

type MyTuple = [
    func: (someArg: boolean) => void,
    arg2: number,
];

class MyClass1 {
    myTuples: MyTuple[] = [];

    someMethod() {
        for (const myTuple of this.myTuples) {
            const [callback, ...args] = myTuple;
            // Look at the type of "args".
            // It is correctly narrowed.
        }
    }
}

// ------------------
// PART 2 - INCORRECT
// ------------------

// This is the same as part 1, but we make it slightly more complicated with
// an interface that maps MyEnum to tuples (instead of just using a single tuple).

enum MyEnum {
    Value1,
    Value2,
}

interface MyParameters {
    [MyEnum.Value1]: [
       func: (someArg: boolean) => void,
       arg2: number,
    ];
    [MyEnum.Value2]: [
        func: (someArg: string) => void,
        arg2: symbol,
    ];
}

class MyClass2<T extends MyEnum> {
    myTuples: Array<MyParameters[T]> = [];

    someMethod() {
        for (const myTuple of this.myTuples) {
            const [callback, ...args] = myTuple;
            // Look at the type of "args".
            // It should be "number | symbol",
            // but it instead incorrectly includes the function types.
        }
    }
}

The type of the variable attached to the spread operator is incorrect.

Furthermore, we can see that the bug is with the spread operator specifically, since accessing the tuple by a specific index returns the correct type.

Other Issues

This is possibly related to #49802.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions