2016-12-11 88 views
5

Mam abstrakcyjną klasę Model z atrybutem statycznym i inną klasą ogólną Controller<T extends Model>. Chcę uzyskać dostęp do statycznego atrybutu Model w instancji kontrolera. To powinno się podoba:Dostęp do statycznego atrybutu statycznego typu ogólnego

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

class MyModel extends Model{ 
    static hasStatus = true; 
} 

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

Ale TS mówi 'T' only refers to a type, but is being used as a value here.

Czy istnieje prosty sposób aby to osiągnąć? Czy powinienem podklasę Controller dla każdego Dziedzictwa Model i wdrożyć metodę, aby pobrać wartość?

+0

W jaki sposób 'T' zwiąże się podczas tworzenia' Kontrolera'? –

Odpowiedz

3

Nie można tego zrobić w maszynopisie. Ogólne parametry typu mogą pojawiać się tylko wtedy, gdy typy mogą pojawiać się w deklaracjach, nie są dostępne w środowisku wykonawczym. Powód jest prosty - funkcja pojedynczego javascript jest generowana dla każdej metody klasy ogólnej i nie ma możliwości, aby ta funkcja wiedziała, który faktyczny typ został przekazany jako parametr typu ogólnego.

Jeśli potrzebujesz tych informacji w czasie wykonywania, trzeba dodać parametr do konstruktora i przekazać typ samodzielnie podczas wywoływania go:

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

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

Oto jak to wygląda, gdy kompilowany do javascript, aby zilustrować punkt - tam nie ma nic z ogólnych parametrów, a jeśli usuniesz parametr cls, nie ma informacji o tym, skąd powinien pochodzić hasStatus.

var Controller = (function() { 
    function Controller(cls) { 
     if (cls.hasStatus) { 
     } 
    } 
    return Controller; 
}()); 
var c = new Controller(MyModel);