How to properly change a variable's type in TypeScript?

ryanrain picture ryanrain · Nov 9, 2015 · Viewed 45.3k times · Source

Thanks for your patience here, I'm just starting out with TypeScript.

I'm working on an angular 2 app that needs to accept text inputs and then make a bunch of calculations. I (incorrectly?) assumed that i would need to first bind inputs to "any" type variables within my data model and then convert those variables to numbers in order to crunch numbers. I've looked all around, and can't find how to do this in such a way that it doesn't throw this TS compiler error:

`src/calculator_service.ts(40,5): error TS2322: Type 'number' is not assignable to type 'string'.`

Within my CalculatorService, I have this function:

/*
 * Convert the object of strings recieved from the form into a clean object of integers
 */
n(model:ModelFields) {
    // Clone it
    this.numericModel = Object.assign({}, this.model);

    for (var prop in this.numericModel) {
        if (this.numericModel.hasOwnProperty(prop)) {

            // strip off all non-numeric charactersklj
            this.numericModel[prop] = this.numericModel[prop].replace(/\D/g,'');

            // convert to Any typescript type
            // this breaks the application, and still throws a compiler error. nope.
            // this.numericModel[prop] = this.numericModel[prop]:Any;

            // convert to Number type
            // this gives a typescript console error, but seems to still compile... 
            // ignoring this for now in order to meet deadline
            this.numericModel[prop] = +this.numericModel[prop];

        }
    }

    return this.numericModel;
}

and the ModelFields definition (thanks tarh!)

export class ModelFields { 
    constructor( 
        public fieldName: any, 
        public anotherField: any 
    ) 
    {} 
}

Any ideas? Thanks everybody!

Answer

josemigallas picture josemigallas · Apr 7, 2016

You cannot change a variable's type in TypeScript, that's just the opposite TS was made for. Instead, you can declare a variable as "any", which would be equivalent to a classic "var" variable in JS, untyped.

Once a variable is declared, you will not be able to retype it. What you could do, however, is to declare "any" and then cast it whenever you want to use it, in order to use it as the desired type.

For example this would not throw any errors:

let a: any;

a = 1234;
(a as number).toExponential();

a = "abcd"; 
(a as string).substr(1, 4);

In case of your class, this would be also correct, no type errors:

class ModelFields { 
    constructor( 
        public fieldName: any, 
        public anotherField: any 
    ) 

    //...
}

let model: ModelFields = new ModelFields(1, 2);

console.log(model.fieldName + model.anotherField);    // --> 3

model.fieldName = "a";
model.anotherField = "b";

console.log(model.fieldName + model.anotherField);    // --> ab