Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript access static attribute of generic type

I have an abstract class Model with a static attribute and another generic class Controller<T extends Model>. I want to access the static attribute of Model in an instance of Controller. That should like this:

abstract class Model{
    static hasStatus: boolean = false;
}

class MyModel extends Model{
     static hasStatus = true;
}

class Controller<T extends Model>{
    constructor(){
        if(T.hasStatus)...
    }
}

But TS says 'T' only refers to a type, but is being used as a value here.

Is there an easy way to achieve this? Or should i subclass Controller for each Heritage of Model and implement a method to retrieve the value?

like image 547
Johannes Kees Avatar asked Dec 11 '16 18:12

Johannes Kees


People also ask

How to access a class with static property in typescript?

The above Circle class includes a static property pi. This can be accessed using Circle.pi . TypeScript will generate the following JavaScript code for the above Circle class. The following example defines a class with static property and method and how to access it. The above Circle class includes a static property and a static method.

How do you create a class type in typescript using generics?

Using Class Types in Generics. When creating factories in TypeScript using generics, it is necessary to refer to class types by their constructor functions. For example, function create < Type > ( c: { new (): Type }): Type {. return new c ();

Is there a way to access attribute keys in typescript?

Typescript is obscurely particular with accessing attribute keys on objects that lack a generic signature. Adding generic signatures reduces type-safety though. Here's a Typescript-friendly way to verify an attribute exists in an object, and then access that attribute.

How to define static members in ES6 typescript?

ES6 includes static members and so does TypeScript. The static members of a class are accessed using the class name and dot notation, without creating an object e.g. <ClassName>.<StaticMember>. The static members can be defined by using the keyword static. Consider the following example of a class with static property.


1 Answers

There is no way to do that in typescript. Generic type parameters can only appear where types may appear in declarations, they are not accessible at runtime. The reason for that is simple - single javascript function is generated for each method of the generic class, and there is no way for that function to know which actual type was passed as generic type parameter.

If you need that information at runtime, you have to add a parameter to the constructor and pass a type yourself when calling it:

class Controller<T extends Model>{
    constructor(cls: typeof Model){
        if (cls.hasStatus) {
        }
    }
}

let c = new Controller<MyModel>(MyModel);

Here is how it looks when compiled to javascript to illustrate the point - there is nothing left of generic parameters there, and if you remove cls parameter there is no information about where hasStatus should come from.

var Controller = (function () {
    function Controller(cls) {
        if (cls.hasStatus) {
        }
    }
    return Controller;
}());
var c = new Controller(MyModel);
like image 139
artem Avatar answered Oct 27 '22 05:10

artem