Union types and overloads acts a bit weirdly
See original GitHub issueAcknowledgement
I have asked the question on Gitter and most of the users believe it’s a bug and I have search for existing issues and didn’t found any.
Issue
Let’s start with the code. Playground link
declare class Foo {
public red(): this
public red(text: string): string
}
declare class Bar {
public red(): this
public red(text: string): string
}
const foo: Foo | Bar = new Foo()
const a = foo.red('text')
In the above code, I expect the variable a
to be a string. However, it is string | Bar
.
Now, things get even weird when I replace string
with object
in the return types of red
method.
declare class Foo {
public red(): this
public red(text: string): object
}
declare class Bar {
public red(): this
public red(text: string): object
}
const foo: Foo | Bar = new Foo()
const a = foo.red('text')
Now suddenly, a
is an object
(which is correct)
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:7 (4 by maintainers)
Top Results From Across the Web
Generics vs Function Overloading vs Union Type Arguments ...
Generic Functions are the only solution you have to solve the common problem between union types and function overloading — the capacity of ......
Read more >Parameter type interface for overloaded functions as union type
If Parameters<T>[0]> returns string & number , then doCall(fn, 0, 0) would incorrectly fail (and be a big breaking change). Notably, with ...
Read more >Debate with colleagues: Union Types. Bad or good? : r/PHP
Anytime you'd overload a method in some other language to allow passing in different types is when you'd use union types in PHP....
Read more >Handbook - Unions and Intersection Types - TypeScript
Union types can be a bit tricky here, but it just takes a bit of intuition to get used to. If a value...
Read more >Union types in Dart? - Google Groups
I think that plain union types would be enough, without intersection types (I've never missed those) or some weird : or & operators....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Its kind of sad that verified bugs are not getting fixed for years. 😦
Some additional fun stuff from our gitter exploration:
Take the original example:
Bar
fixesa
foo: Bar | Foo
makesa: string | Foo
Baz
(or more) and appending the type tofoo
’s union also appends it to the type ofa
I think that’s all I had. But it does trigger one peeve of mine: conceptually, I don’t expect the ordering within a union or intersection to matter. It’s been pointed out that overloads are represented as intersections, so ordering matters there. So I think this may be the smallest example that shows ordering sensitivity in both a union and an intersection.
😠
Also @RyanCavanaugh can you elaborate on the ‘right’ order of overloads since I don’t know of it being documented anywhere? I was thinking that it makes sense to order from more specific to more generic. My first thought was that the nullary version was most specific, but then it occurred to me that 1 arg is more ‘specified’ than no args, so maybe I had it backwards. If you could help my intuition there that would be great.