37

I have three variable in my Typescript class :

A:number;
B:number;
C:number;

in another part of the class i try to make the addition of the two variable A and B :

this.C = this.A+this.B; // A =20 and B = 50;

and I display C in the html template

<span>{{C}}</span>

My problem is, instead of getting the addition of the TWO variable (20+50=70) i get the concatenation (2050)!!

Can someone help me please ?

UPDATE :

Here is the exact code portion that cause problem :

goTo(page:number,type:script) {
    //    
    this.pageFirstLineNumber = page;
    this.pageLastLineNumber = page + this.LINE_OFFSET; //concatenation!!
}

Notice that pageLastNumber is declared as number type, LINE_OFFSET is olso number type, i have found a solution to this issue but the typescript compiler output an error (forbidden eval):

////
....
this.pageFirstLineNumber = eval(page.toString()); // now It works !!
this.pageLastLineNumber = page + this.LINE_OFFSET; //concatenation!!

UPDATE

Here is the declaration of the LINE_OFFSET variable :

private _calculateOffset(fontSize: number) {
    let linesDiff = (fontSize * 27) / 14;
    let lines:number = 27 - (linesDiff - 27);
    this.LINE_OFFSET = Math.floor(lines);
    if (fontSize >= 17 && fontSize <= 20) {
        this.LINE_OFFSET += (Math.floor(fontSize / 3) - 2);
    }
    if (fontSize > 20 && fontSize <= 23) {
        this.LINE_OFFSET += (Math.floor(fontSize / 2) - 2);
    }
    if (fontSize > 23 && fontSize <= 25) {
        this.LINE_OFFSET += (Math.floor(fontSize / 2));}
    if (fontSize > 25 && fontSize <= 27) {
        this.LINE_OFFSET += (Math.floor(fontSize / 2) + 1);
    }
    if (fontSize > 27 && fontSize <= 30) {
        this.LINE_OFFSET += (Math.floor(fontSize / 2) + 4);
    }
}
Nacim Idjakirene
  • 1,882
  • 8
  • 26
  • 45
  • 1
    Please add to your question the part where you assign values to `A` and `B` – Nitzan Tomer Sep 01 '16 at 11:04
  • 1
    It makes no difference how those properties are declared, if at runtime you get a string then it's a string regardless of if they were declared as numbers. How is `this.LINE_OFFSET` assigned? Also, don't use `eval`, use `parseInt` or `parseFloat` or `Number` – Nitzan Tomer Sep 01 '16 at 15:20

7 Answers7

61

prepend the numbers with +:

let a = +b + +c;

ref

Marvin Zumbado
  • 1,005
  • 1
  • 9
  • 10
  • 2
    I don't know why OP didn't choose this simple solution. May be it's not practical? – Vijay Kumar Kanta Jul 12 '19 at 06:03
  • 1
    @VijayKumarKanta it doesn't address the core of the problem where you've overruled TypeScript's type inference. You now have to *overrule the overrule*. So, you're not actually using TypeScript - you're writing JavaScript with extra steps and don't benefit from any of the core features of TS. – VLAZ Feb 03 '20 at 14:50
27

When you declare in an interface that a property is a number then it stays as a declaration only, it won't be translated into javascript.

For example:

interface Response {
    a: number;
    b: number;
}

let jsonString = '{"a":"1","b":"2"}';
let response1 = JSON.parse(jsonString) as Response;

console.log(typeof response1.a); // string 
console.log(typeof response1.b); // string
console.log(response1.a + response1.b); // 12

As you can see, the json has the a and b as strings and not as numbers and declaring them as numbers in the interface has no effect on the runtime result.

If what you get from your server is encoded as strings instead of numbers then you'll need to convert them, for example:

let response2 = {
    a: Number(response1.a),
    b: Number(response1.b)
} as Response;

console.log(typeof response2.a); // number 
console.log(typeof response2.b); // number
console.log(response2.a + response2.b); // 3

(entire code in playground)

Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299
2

Problem is variable typecasting not done. You need to do in following way.

A : parseInt(number); B : parseInt(number);

then you will get sum C= A+b instead of concatenation.

Smit Shah
  • 314
  • 1
  • 3
  • 13
2

I ran into similar problem , was able to solve as below :

C:number =0;
A:number=12;
B:number=0.4;
C= Number.parseInt(A.toString()) + Number.parseFloat(B.toString());
console.log("C=" + C );

seems stupid , to convert a number to string and parse again to number , but this is how I solved my problem.

pritesh agrawal
  • 1,155
  • 8
  • 16
1

Finnaly i find what cause the error, i get the page variable from the html template (its an input value), it is defined as number type in the function parameter, but in reality is a string and typescript cant check the type of variable from html template, so when a try parseInt(page) static typping highlight an error ! i have soved the issue by giving the page variable an "" type, then applying parseInt to the page variable.

Nacim Idjakirene
  • 1,882
  • 8
  • 26
  • 45
  • thank you for the explanation, I could not figure out why it was a string even thou my form model declared the field as a number. I would have expected for the value returned by the input element to be cast to a number – Johnny Oct 21 '22 at 17:02
0

That means there are string values in either A or B variables. Check your code for unsafe parts, I mean casting to <any>, and casting server responses to interfaces. That could cause to have string values in number variables.

Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
  • In my server response interfaces , the variables i'am trying to display are declared in "number " type ! – Nacim Idjakirene Sep 01 '16 at 12:21
  • @NacimIdjakirene Did you check the server response? Maybe the type interface is just wrong! If the server response doesn't match the type interface in typescript, it remains undetected as typescript will not perform runtime type checks, it just assumes the right types. – Tamas Hegedus Sep 01 '16 at 12:46
0

const value = Number(stringOrNum)+1;

Dinesh
  • 1