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

63,470

Solution 1

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

Solution 2

You example is not clear enough, but I guess that your problem is because of Typescript inference:

var x = 3; // x is a number
x = "45";  // compiler error

But, if you do:

var x : any = 3; // x can be anything
x = "45";

Or:

var x; // x is any forever
x = '45';  // x is still any

You can find further details on those great slides and on docs

Hope this can help a bit...

Share:
63,470

Related videos on Youtube

ryanrain
Author by

ryanrain

Updated on July 09, 2022

Comments

  • ryanrain
    ryanrain almost 2 years

    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!

    • Paleo
      Paleo over 8 years
      What is the definition of ModelFields?
    • ryanrain
      ryanrain over 8 years
      @Tarh export class ModelFields { constructor( public fieldName: any, public anotherField: any ) {} }
    • josemigallas
      josemigallas about 5 years
      @ryanrain it's been a long time but I'm curious at this point, did my post answer your question?
  • ryanrain
    ryanrain over 8 years
    Thanks a lot Yaniv, and sorry for my lack of clarity. I think I understand the concept of TypeScript inference - very important. In my code it's probably my use of the replace string method that makes TypeScript infoer that my model is an object of strings.
  • ryanrain
    ryanrain over 8 years
    To clarify, I'm trying to ask if it's possible to explicitly and correctly change a variable's type, say from a string to a number, without causing a compiler error. Does this make sense?
  • MikeMurko
    MikeMurko over 7 years
    URL broken for slides.
  • 0zkr PM
    0zkr PM about 5 years
    Just add a plus sign: +this.route.snapshot.params['articleId']
  • Louis
    Louis over 2 years
    In this scenario you should use "unknown" instead of "any". You should avoid using "any" unless absolutely necessary.