Given this code:
type Foo = {
func(a:string):void;
func(b:number, a:string):void;
}
const f:Foo = {
func(b, a) {
// ???
}
}
I get the error
Type '(b: number, a: string) => void' is not assignable to type '{ (a: string): void; (b: number, a: string): void; }'.ts(2322) index.ts(15, 3): The expected type comes from property 'func' which is declared here on type 'Foo'
I see answers using classes, but how to implement on plain objects?
CodePudding user response:
The compiler is apparently unhappy that func(b, a)
requires a second argument while the func
method of Foo
does not. You can get rid of the error by making a
optional in the implementation:
const f: Foo = {
func(b, a?) {
// ^-- optional
}
}
Note that in general it's not always possible to find a way to do this that will compile. Overloaded function statements allow their implementation to be more loosely typed than any of the call signatures, but overloaded function expressions don't work that way:
function barFunc(a: string): number;
function barFunc(b: number, a: string): string;
function barFunc(b: string | number, a?: string) {
return typeof b === "string" ? b.length : a // okay
}
type Bar = {
func(a: string): number;
func(b: number, a: string): string;
}
const g: Bar = {
func(b, a?) { // error!
return typeof b === "string" ? b.length : a
}
}
There's a feature request at microsoft/TypeScript#47669 to allow for arrow functions to be overloaded the same way that function statements are, but for now it's not part of the language.
So if you do find yourself with an impossible-to-implement overloaded arrow function, you should either refactor to a function statement:
const h: Bar = { func: barFunc }; // okay
Or use type assertions to loosen the type checking enough to get it to compile:
const i: Bar = {
func(b, a?) {
return (typeof b === "string" ? b.length : a) as any // okay
}
}