1

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?

2
  • 1
    For that particular example you can write func(b, a?) {} and it'll work, but for more general examples you'd run into trouble. Does that suffice for you or are you looking for something more general? Commented Dec 21, 2022 at 21:29
  • 1
    Yeah, it's ugly, but functional. Thanks! Commented Dec 21, 2022 at 21:34

1 Answer 1

1

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
  }
}

Playground link to code

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.