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

利列克

我有一个装饰班:

@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哪种类型,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.
      });
    }
  };
}

但这在行中给出了一个错误@Decorator

类型“实体”中缺少属性“原型”。

Edit2:我也测试过:

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) => {
        // ...
      });
    }
  };
}

但这在行中给出了一个错误@Decorator

类型“实体”中缺少属性“原型”。

尼桑·托默尔

你可以这样做:

(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: Entitynot 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) {
    ...
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章