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

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

Closed
jimlloyd opened this issue Feb 13, 2015 · 6 comments
Closed
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead

Comments

@jimlloyd
Copy link

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?

@danquirk
Copy link
Member

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 danquirk added the By Design Deprecated - use "Working as Intended" or "Design Limitation" instead label Feb 13, 2015
@cokenias
Copy link

@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'.

@jimlloyd
Copy link
Author

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.

@nitzantomer
Copy link

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.

@RyanCavanaugh
Copy link
Member

See also #2361

@ghost
Copy link

ghost commented Nov 14, 2017

This works :)

example: any = 0;

this.example += 10;

@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead
Projects
None yet
Development

No branches or pull requests

5 participants