23

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?

1
  • How does T get bound when creating a Controller? Commented Dec 11, 2016 at 19:23

1 Answer 1

18

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);
Sign up to request clarification or add additional context in comments.

1 Comment

I think typescript generics and class statics, especially when they are combined, needs to be overhauled. You can't do anything with them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.