Tamás Sallai
Tamás Sallai

Reputation: 3365

Typescript no compatible call signatures error with union types

I have 2 classes, both of them having a function with the same name, but they expect a different argument object:

class C1 {
    public f: (params: { a: string }) => {
    }
}
class C2 {
    public f: (params: { b: string }) => {
    }
}

Then I have a function that gets C1 | C2, and I try to call the function with a config object that has all the properties for both C1.f and C2.f.

But this gives an error:

const fx = (c: C1 | C2) => {
    const params = { a: "a", b: "b" };
    c.f(params);
}

The best solution I could come up with is to add an instanceof to implicitly cast c to C1 and C2 and call the function:

if (c instanceof C1) {
    c.f(params);
} else {
    c.f(params);
}

Typescript playground link

Is there a simpler way to call the common function without typecasting?

Upvotes: 2

Views: 491

Answers (2)

code_x386
code_x386

Reputation: 798

Try this code:

const fx = (c: C1 | C2) => {
    const params = { a: "a", b: "b" };
    type T = (params: { a: string; b: string; }) => void;
    let f_: T = c.f;
    f_(params);
}

Upvotes: 0

Buh Buh
Buh Buh

Reputation: 7546

//Ensure that when f is called, the params must have both `a` and `b`:
interface IC {
    f: (params: { a: string } & { b: string }) => {};
};
//Here it is fine to assume that the params contain a:
class C1 implements IC {
    public f: (params: { a: string }) => {
    }
}
//Here it is fine to assume that the params contain `b`:
class C2 implements IC {
    public f: (params: { b: string }) => {
    }
}
const fx = (c: IC) => {
    const params = { a: "a", b: "b" };
    c.f(params);
}

Upvotes: 2

Related Questions