How to properly change a variable's type in TypeScript?
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...
Related videos on Youtube
ryanrain
Updated on July 09, 2022Comments
-
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 over 8 yearsWhat is the definition of
ModelFields
? -
ryanrain over 8 years@Tarh
export class ModelFields { constructor( public fieldName: any, public anotherField: any ) {} }
-
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 over 8 yearsThanks 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 mymodel
is an object of strings. -
ryanrain over 8 yearsTo 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 over 7 yearsURL broken for slides.
-
0zkr PM about 5 yearsJust add a plus sign:
+this.route.snapshot.params['articleId']
-
Louis over 2 yearsIn this scenario you should use "unknown" instead of "any". You should avoid using "any" unless absolutely necessary.