question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

proper overloading for arrow functions

See original GitHub issue

Suggestion

🔍 Search Terms

arrow function overload

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn’t be a breaking change in existing TypeScript/JavaScript code
  • This wouldn’t change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript’s Design Goals.

⭐ Suggestion

it seems that the syntax for overloading arrow functions are more like a side effect of existing functionality (function interfaces/intersections), rather than an intentional language feature. as a result, it doesn’t really work properly in most cases - see #33482

it would be nice if there was actual syntax for arrow function overloading like there is for normal functions

📃 Motivating Example

const foo: {
    (value: number): number
    (value: string): string
} = (value) => value

this is the most basic example of an overload i can think of, yet it doesn’t work:

Type '(value: string | number) => string | number' is not assignable to type '{ (value: number): number; (value: string): string; }'.
  Type 'string | number' is not assignable to type 'number'.
    Type 'string' is not assignable to type 'number'.(2322)

as mentioned on https://github.com/microsoft/TypeScript/issues/33482#issuecomment-533058120, function interfaces have a much broader purpose than overloads, meaning it has to protect against a potentially incorrect assignment in other scenarios. but here, that’s obviously not what we want

perhaps a function overload type that looks something like:

const foo: overload {
    (value: number): number
    (value: string): string
} = (value) => value

💻 Use Cases

makes it easier to avoid using old function syntax

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:12
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

5reactions
DetachHeadcommented, Apr 2, 2022

an idea i came up with to solve the issue without adding any additional syntax is to improve the logic used to infer the type of the implementation when its types are omitted.

for example:

const foo: {
    (value: number): number
    (value: string): string
} = (value) => value

currently the value is inferred as (value: string | number) => string | number which is wrong. it should be instead inferred as <T extends string | number>(value: T) => T. that way you would get no errors on assignment, and you wouldn’t have to do any casting in the impl

obviously this could get messy with some more complicated overloads though:

const foo: {
    (value: number, value2: string): number
    (value: string): string
} = (value1, value2) => value

in this case perhaps there could be a built in Overload interface to simplify the inferred type of the impl:

interface Overload<Parameters extends unknown[], Return> {
    parameters: Parameters
    return: Return
}

then the impl can be inferred as something like

<O extends Overload<[number, string], number> | Overload<[string], string>>(
    ...args: O['parameters']
) => O['return']

(though while playing around with this approach i ran into other issues such as #48345 and #46076)

1reaction
erquhartcommented, Dec 27, 2022

Yeah, fair - I was more thinking of js support for declaring functions that have already been declared, and doing so with constants feels a bridge further. But yeah, not materially different since neither is really valid, agreed. Your syntax is honestly preferable if using const this way isn’t an issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Typescript overload arrow functions - Stack Overflow
I'd like to use a generic to overload for different types. I'm trying different thing but unable to get the syntax right. –...
Read more >
TypeScript function overloads - DEV Community ‍ ‍
Today I want to write a little bit about functions overloads in TypeScript. I will explain what is function overload and how to...
Read more >
Typing Functions with Overloading, Values, and Arrow Functions
Overloading allows us to to define multiple function signatures for one function. We can think of it as pattern matching based on the...
Read more >
Steve Ruiz on Twitter: "TIL you can write overloads for arrow ...
TIL you can write overloads for arrow functions in TypeScript. Image. 9:24 AM · Feb 20, 2022 ... It's not a very good...
Read more >
A Simple Explanation of Function Overloading in TypeScript
Function overloading in TypeScript lets you define functions that can be called in multiple ways. Using function overloading requires defining ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found