38

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);
    }
}
2
  • 1
    Please add to your question the part where you assign values to A and B Commented Sep 1, 2016 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 Commented Sep 1, 2016 at 15:20

7 Answers 7

61

prepend the numbers with +:

let a = +b + +c;

ref

Sign up to request clarification or add additional context in comments.

2 Comments

I don't know why OP didn't choose this simple solution. May be it's not practical?
@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.
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)

Comments

3

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.

1 Comment

It's not typecasting, it's conversion. Also, in his example number is not a variable but a type declaration.
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.

Comments

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.

1 Comment

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
1

const value = Number(stringOrNum)+1;

Comments

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.

2 Comments

In my server response interfaces , the variables i'am trying to display are declared in "number " type !
@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.

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.