我想知道为什么当我在类的 Typescript 中使用装饰器或注释时。编译器无法推断该类的新类型。如果我不使用装饰器并使用 ES5 中的旧方法来执行此操作(即手动调用装饰器),它显然可以工作。
例如,这里有一个显示问题的示例:
function decorate(Target: typeof Base): IExtendedBaseConstructor {
return class extends Target implements IExtendedBase {
public extendedtMethod(): number {
return 3;
}
};
}
interface IBase {
baseMethod(): number;
}
interface IExtendedBase extends Base {
extendedtMethod(): number;
}
interface IExtendedBaseConstructor {
new(): IExtendedBase;
}
@decorate
class Base implements IBase {
public baseMethod(): number {
return 5;
}
}
const test = new Base();
test.baseMethod(); // OK
test.extendedtMethod(); // NOT OK, typescript think, Base is still Base but we decorated it.
使用旧方法,它可以工作:
class Base implements IBase {
public baseMethod(): number {
return 5;
}
}
const ExtendedBase = decorate(Base);
const test = new ExtendedBase();
test.baseMethod(); // OK
test.extendedtMethod(); // OK
提前致谢。
目前这不起作用。 github 上有一个悬而未决的问题,允许类装饰器更改类的类型。
我建议采用您提到的“旧方法”,直到实施为止。
有一种方法可以让这项工作只需要一点额外的编码。
对于任何类装饰器,创建一个带有其属性和方法的接口。以某种方式命名它,以便您可以轻松地将它与它所描述的装饰器关联起来。在你的情况下,它可能是:
interface IDecorate {
extendedMethod(): number;
}
对于任何需要此装饰器的类,您只需创建一个与该类同名的接口,并让它扩展所有必要的装饰器接口:
@decorate
@anotherDecorator
class MyClass {
// ...
}
interface MyClass extends IDecorate, IAnotherDecorator {}
现在,只需关闭 ESLint 或 TSLint 对空接口的警告,您就可以开始了。装饰器添加的任何方法或属性现在都可以在装饰类本身中使用。