3

I am trying to teach students the intricacies of things like polymorphism via (in this case built-in) operator overloading, and I created an example I thought should work but didn't. I would love some insight from Typescript experts as to why this example fails.

function add2(a: number) {
  return a + 2;
} // works fine, adds 2 and returns a number

function concat2(a:string) {
  return a + 2;
} // works fine, concatenates '2' and returns a string

function addOrConcatenateTwo(a: string | number) {
  return a + 2;
} 
// compile error. I THOUGHT it would return a string | number but it errors out no matter what.

I thought that Typescript would see that + is defined for strings and + is also defined for numbers and it would allow the last function to run. That's how it works for shared method names across interfaces, so why does the + operator work differently?

This works fine and does exactly what I thought my example above would do. Is this a bug? Admittedly, one that would likely only appear in artificial educational scenarios?

function addOrConcatenateTwo(a: string | number) {
    if (typeof (a) == "string") {
        return a + 2;
    } else {
        return a + 2;
    }
}
5
  • 3
    Does this answer - especially second half - help you out? In essence the + operator does not work with union types. Commented Oct 23, 2019 at 12:33
  • It does! Well, sort of - it tells me that what I've discovered is, in fact, true, but it doesn't really address why. Is this a philosophical decision (and if so, what is the reasoning behind it) or just an implementation reality? Commented Oct 23, 2019 at 13:11
  • 1
    Cannot speak for the TS developers here, so just some speculations: I think, above is a very rare use case (in most cases you want to do a calculation xor a concatenation) and the team may have decided, that this construct is more likely to be an error according to TS design goals. Also it is stated that TS is not considered as 'sound or "provably correct' type system. Instead, strike a balance between correctness and productivity.", so that could be a point in favor of practicability. Commented Oct 23, 2019 at 16:31
  • 1
    Here is a statment from one of the developers that goes in your diretion: "T + T where T extends string | number is still disallowed -- we don't feel this is a good use case because whether you get concatenation or addition is not predictable, thus something that people shouldn't be doing." That can be even more transferred to a simple union type string | number like in above case. Instead it is suggested to e.g. use function overloads Commented Oct 23, 2019 at 16:31
  • 1
    Okay, so a (totally fair) philosophical decision. I even understand it! It just means I'll have to jump straight to method overloads to get into this idea, which is fine. I appreciate your time! Commented Oct 23, 2019 at 17:58

0

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.