从装饰器访问泛型类的静态成员

时间:2017-07-27 10:07:35

标签: typescript generics inheritance

我有一个装饰类:

@Decorator
class Entity {
    public static member: string[] = [];
}

带装饰者:

function Decorator<T extends { new(...args: any[]): Entity }>(constructor: T) {
  return class extends constructor {
    constructor(...args: any[]) {
      super(...args);
      // Do some things
      constructor.prototype.member.map((v: string) => {
        // Do things with the elements of the static array.
      });
    }
  };
}

虽然这很有效,但是通过使用类型为constructor.prototype的{​​{1}},我丢失了原型中已经作为字符串数组的any的类型检查。

有没有丢失类型检查的解决方案?

修改:我也进行了测试:

member

但这会在行function Decorator<T extends { prototype: typeof Entity; new(...args: any[]): Entity; }>(constructor: T) { return class extends constructor { constructor(...args: any[]) { super(...args); // Do some things constructor.prototype.member.map((v) => { // Do things with the elements of the static array. }); } }; } 中出现错误:

  

物业&#39;原型&#39;类型&#39;实体&#39;&#39;

中缺少

Edit2 :我也经过了测试:

@Decorator

但这会在行function Decorator<T extends typeof Entity>(constructor: T) { // This works and returns an Entity. const x = new constructor({} as any); // This doesn't work. Tsc says: 'Type 'T' is not a constructor function type.' return class extends constructor { constructor(...args: any[]) { super(...args); // This now works: constructor.member.map((v) => { // ... }); } }; } 中出现错误:

  

物业&#39;原型&#39;类型&#39;实体&#39;&#39;

中缺少

1 个答案:

答案 0 :(得分:1)

你可以这样做:

(constructor.prototype as typeof Entity).member...

然后你会有类型安全,例如:

(constructor.prototype as typeof Entity).member2..

将导致:

  

属性'member2'在类型'typeof Entity'上不存在。

修改

你做不到。
静态成员/函数是原型的一部分,为了做你想做的事情,它应该是这样的:

function Decorator<T extends { prototype: Entity; new(...args: any[]): Entity; }>(constructor: T) { ... }

(差异为prototype: Entity而非typeof Entity),您收到的错误将消失。
但是,那么你会得到错误:

  

属性'成员'在'实体'

类型上不存在

因为它是一个静态成员。

Entity类的编译js中很容易看到:

var Entity = (function () {
    function Entity() {
    }
    return Entity;
}());
Entity.member = [];

显然,member不是原型的一部分。

正如我原来的回答所说,这就是你需要施展它的原因。

第二次编辑

这是可行的,也可能是你所追求的东西:

type EntityStatic = {
    new (...args: any[]): Entity;
    member: string[];
}

function Decorator(constructor: EntityStatic) {
    ...
}