Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible to implement overloaded call signature with an arrow function? #38622

Closed
bcherny opened this issue May 17, 2020 · 1 comment
Closed
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@bcherny
Copy link

bcherny commented May 17, 2020

TypeScript Version: 4.0.0-dev

Search Terms: Function overload, signature, declaration

Code

type CreateElement = {
  (tag: 'a'): HTMLAnchorElement
  (tag: string): HTMLElement
}

/*
  Error TS2322:
    Type '(tag: string) => HTMLAnchorElement | HTMLDivElement' is not assignable to type 'CreateElement'.
      Type 'HTMLAnchorElement | HTMLDivElement' is not assignable to type 'HTMLAnchorElement'.
*/
const createElement: CreateElement = (tag: string) => {
  if (tag === 'a') {
    return document.createElement('a')
  }
  return document.createElement('div')
}

TS infers createElement's signature as (tag: string) => HTMLAnchorElement | HTMLDivElement, which is not assignable to CreateElement. Could there be a way to treat this case similarly to how TS treats function-based overloads, so instead of checking that the right-hand-side of the assignment is compatible with the left-hand type (CreateElement), TS instead checks that each case of the overload (in CreateElement) is assignable to the right-hand-side? Or if this is too radical of a departure from TS's assignability checking, could there be another way to make this work?

Expected behavior: TS should treat function and function expression overloads the same. This code should work, the same way that the following code works:

function createElement(tag: 'a'): HTMLAnchorElement
function createElement(tag: string): HTMLElement {
   return document.createElement(tag)
}

Actual behavior: TypeError

Playground Link

Related Issues:

@bcherny bcherny changed the title TypeError when implementing overloaded call signature with an arrow function Possible to implement overloaded call signature with an arrow function? May 19, 2020
@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Jun 8, 2020
@RyanCavanaugh
Copy link
Member

The posted "equivalent" has only one overload; it is not at all equivalent 😐

The only way to detect that this is a valid assignment is to read the function body and understand that it behaves correctly in each overload case; it is far beyond TS's capabilities to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

2 participants