Typescript: error TS2365: Operator '+' cannot be applied to types 'Number' and 'Number'.

Created on 13 Feb 2015  路  6Comments  路  Source: microsoft/TypeScript

Given index.ts:

var a: Number = new Number(1);
var b: Number = new Number(2);
var c: number = 3;
console.log(a+b);
console.log(b+c);

When compiled, the compiler produces these errors:

index.ts(4,13): error TS2365: Operator '+' cannot be applied to types 'Number' and 'Number'.
index.ts(5,13): error TS2365: Operator '+' cannot be applied to types 'Number' and 'number'.

But if I don't use --noEmitOnError, the compiler produces this index.js:

var a = new Number(1);
var b = new Number(2);
var c = 3;
console.log(a + b);
console.log(b + c);

Which I can run with node and get expected results:

$ node index.js 
3
5

Why does the compiler refuse to allow addition of two Numbers, or a Number and a number?

By Design

Most helpful comment

The language of section 4.15.2 is confusing because it only says Number (with a capital N) but then says primitive type, which implies number (with a lowercase n). If the Typescript team really is going to insist that only number types can be added, and that Number types cannot, then I think that section of the spec should be clarified.

But I want to protest this stance.

First, you can't say 'in practice people aren't creating number via new Number', because you obviously don't have full knowledge of all javascript practice. I am a user (and minor contributor) to node-java, a bridge API that allows node.js applications to launch an embedded JVM and execute Java code. The node-java API returns javascript Number objects everywhere a Java method returns a numeric type.

Second, yes, you provided an artificial example how someone can create a var with a Number interface, but do you think that people do that _in practice_? Do you think that a programmer who did that would complain to you that applying operator+ to his var yielded incorrect results, and deny that his code was nonsensical?

Finally, I want typescript to catch at compile-time errors in use of types that are likely to result in errors at runtime, and not yield compile-time errors when the emitted code is unlikely to lead to a compile time error. I know there is a probably a lot of gray area here, but when in doubt, typescript should _do no harm_, i.e not prevent a programmer from using correct Javascript. If the Javascript spec disallowed adding two Numbers, or adding a Number to a number, then Typescript clearly should too. But it is wrong for Typescript to disallow something so simple as adding two numbers.

All 6 comments

Section 4.15.2 of the spec notes:

_The binary + operator requires both operands to be of the Number primitive type or an enum type, or at least one of the operands to be of type Any or the String primitive type_

If the compiler allowed Numbers to be added then it would permit things like:

var n: Number = { 
    toFixed(x?: number) { return ''},
    toExponential(x?: number) { return ''},
    toPrecision(x?: number) { return ''} 
}

var r = n + 3;
console.log(r); // r is ?

and in practice people aren't creating number via new Number

@danquirk, does this seem correct to you?

_"The binary + operator requires both operands to be of the Number primitive type or..."_
index.ts(4,13): error TS2365: Operator '+' cannot be applied to types 'Number' and 'Number'.

The language of section 4.15.2 is confusing because it only says Number (with a capital N) but then says primitive type, which implies number (with a lowercase n). If the Typescript team really is going to insist that only number types can be added, and that Number types cannot, then I think that section of the spec should be clarified.

But I want to protest this stance.

First, you can't say 'in practice people aren't creating number via new Number', because you obviously don't have full knowledge of all javascript practice. I am a user (and minor contributor) to node-java, a bridge API that allows node.js applications to launch an embedded JVM and execute Java code. The node-java API returns javascript Number objects everywhere a Java method returns a numeric type.

Second, yes, you provided an artificial example how someone can create a var with a Number interface, but do you think that people do that _in practice_? Do you think that a programmer who did that would complain to you that applying operator+ to his var yielded incorrect results, and deny that his code was nonsensical?

Finally, I want typescript to catch at compile-time errors in use of types that are likely to result in errors at runtime, and not yield compile-time errors when the emitted code is unlikely to lead to a compile time error. I know there is a probably a lot of gray area here, but when in doubt, typescript should _do no harm_, i.e not prevent a programmer from using correct Javascript. If the Javascript spec disallowed adding two Numbers, or adding a Number to a number, then Typescript clearly should too. But it is wrong for Typescript to disallow something so simple as adding two numbers.

Allowing operators on other object types lets developers the option to "override" operators.
Consider the following snippet:

class MyNumber {
    private value: number;

    constructor(value: number) {
        this.value = value;
    }

    valueOf(): number {
        return this.value
    }
}

var myNum1: MyNumber = new MyNumber(10);
var myNum2: MyNumber = new MyNumber(5);

var n: number = myNum1 + myNum2;
console.log(n); // prints 15

(checkout in playground)

The compiler is complaining about _Operator '+' cannot be applied to types 'MyNumber' and 'MyNumber'_ but it works as before the operator is applied each operand's _valueOf()_ method is called, and so by overriding it you can have some control over different operations.
As this can be useful, in my opinion it should not be restricted as it is now.

There are more tricks you can do with this, check out this article Fake operator overloading in JavaScript.

See also #2361

This works :)

example: any = 0;

this.example += 10;

Was this page helpful?
0 / 5 - 0 ratings

Related issues

uber5001 picture uber5001  路  3Comments

MartynasZilinskas picture MartynasZilinskas  路  3Comments

DanielRosenwasser picture DanielRosenwasser  路  3Comments

wmaurer picture wmaurer  路  3Comments

manekinekko picture manekinekko  路  3Comments