A spread argument must either have a tuple type or be passed to a rest parameter.ts(2556)

Viewed 296

Hi I am trying to create a wrapper for an add function that is declared like this:

add(target: Object, propName:string, min?: number, max?: number, step?: number): GUIController;
add(target: Object, propName:string, status: boolean): GUIController;
add(target: Object, propName:string, items:string[]): GUIController;
add(target: Object, propName:string, items:number[]): GUIController;
add(target: Object, propName:string, items:Object): GUIController;

If I do the following for one of the declarations it works:

add(...args: [Object, string, number?, number?, number?]) {
    return this.gui.add(...args);      <--- this works, but I want to do this for multiple signatures
}

So I try to combine different arguments into one. But I get an error saying A spread argument must either have a tuple type or be passed to a rest parameter.ts(2556):

type AddArg = 
    [Object, string, number?, number?, number?] |
    [Object, string, boolean] |
    [Object, string, string[]] |
    [Object, string, number[]] |
    [Object, string, Object];

add(...args: AddArg) {
    return this.gui.add(...args);      <--- A spread argument must either have a tuple type or be passed to a rest parameter.ts(2556)
}

Each of the types in AddArg is a tuple type, but typescript did not see this, may I know how can I fix this?

An example can be found here

1 Answers

I hadn't yet seen your playground when I commented, but here's an example how arguments can work with those classes you had:

type AddArg = 
    [Object, string, number?, number?, number?] |
    [Object, string, boolean] |
    [Object, string, string[]] |
    [Object, string, number[]] |
    [Object, string, Object];

class SomeClass {
    add(..._args: AddArg[]) {
        return;
    }
}

export class MyClass {
    someClass: SomeClass
    constructor() {
        this.someClass = new SomeClass();
    }

    add(...args: AddArg) {
        return this.someClass.add(...arguments);      
    }
}

let a = new MyClass();

a.add({ foo: "bar"}, "baz", 3, 5, 1);
a.add({ foo: "bar"}, "baz", 3, 5);
a.add({ foo: "bar"}, "baz", 3);
a.add({ foo: "bar"}, "baz");
a.add({ foo: "bar"}, "baz", true);
a.add({ foo: "bar"}, "baz", ["blah, blah"]);
a.add({ foo: "bar"}, "baz", [1, 2, 3]);
a.add({ foo: "bar"}, "baz", { bar: "foo"});

// invalid
a.add({ foo: "bar"}, "baz", 3, "blah");

Live playground

Related