The default value of a type in common classes in Typescript

I need to set a default value for a variable based on its type in Typescript generic classes, as shown below

class MyClass<T>{ myvariable: T // Here I want to set the value of this variable // with the default value of the type passed in 'T' } 

For example, if T is a number, then the default value of the myvariable variable should be "0", similarly for a string it should be an empty string and so on ..

+5
source share
3 answers

You cannot do this, since the actual type T will only be known at run time.

What can you do:

 abstract class MyClass<T> { myvariable: T; constructor() { this.myvariable = this.getInitialValue(); } protected abstract getInitialValue(): T; } 

Now you just extend this class, for example:

 class MyStringClass extends MyClass<string> { protected getInitialValue(): string { return "init-value"; } } 

Edit

What you are requesting cannot be done because T exists only in the typescript area and it does not "survive" during the compilation process.

For example, this:

 class MyClass<T> { myvariable: T; constructor(value: T) { this.myvariable = value; } } 

Compiles to:

 var MyClass = (function () { function MyClass(value) { this.myvariable = value; } return MyClass; }()); 

As you can see, the compiled version does not have T , so you cannot use this information at run time to create a default value.


Another solution is to have a map of default values:

 var defaultValues = { "string": "", "number": 0, "boolean": false } class MyClass<T> { myvariable: T; constructor(value: T) { this.myvariable = value; } } let a = new MyClass<string>(defaultValues.string); let b = new MyClass<boolean>(defaultValues.boolean); 

You can also use static factory methods:

 class MyClass<T> { myvariable: T; constructor(value: T) { this.myvariable = value; } static stringInstance(): MyClass<string> { return new MyClass<string>(""); } static numberInstance(): MyClass<number> { return new MyClass<number>(0); } static booleanInstance(): MyClass<boolean> { return new MyClass<boolean>(false); } } let a = MyClass.stringInstance(); let b = MyClass.booleanInstance(); 
+5
source

T is lost at runtime, so you need to pass the type of the value type. And you can do this by passing a constructor.

When I have a similar need, I usually use this interface:

 interface Type<T> { new() : T; } 

And create MyClass as follows:

 class MyClass<T>{ myvariable: T; constructor(type: Type<T>) { this.myvariable = new type(); } } 

Then I can use MyClass as follows:

 let myinstance = new MyClass(TheOtherType); 

It works for classes, but not for inline strings such as string and number.

TheOtherType is a constructor for a class such as:

 class TheOtherType { } 
0
source

Well, I think I came up with a possible solution. In any case, I must say that Nitzan Tomer is right and the class type is not available at runtime. This is the funny side of TS :)

Here you can check the type of objects you receive, and then set the default value. You can also change the location and objects to check to make it the way you want, but I think this may be a good starting point for you. Note that you need to do a double throw because TS cannot guarantee type compatibility. I haven't tried it yet, but it compiles well

 class MyClass<T>{ myvariable: T constructor(param: any) { if (typeof param === 'string') { this.myvariable = <T><any> ""; } else if (typeof param === 'number') { this.myvariable = <T><any> 0; } } } 
0
source

All Articles