Typescript:使用装饰器时进行类型推断

问题描述 投票:0回答:2

我想知道为什么当我在类的 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

提前致谢。

javascript oop typescript decorator
2个回答
4
投票

目前这不起作用。 github 上有一个悬而未决的问题,允许类装饰器更改类的类型。

我建议采用您提到的“旧方法”,直到实施为止。


0
投票

有一种方法可以让这项工作只需要一点额外的编码。

对于任何类装饰器,创建一个带有其属性和方法的接口。以某种方式命名它,以便您可以轻松地将它与它所描述的装饰器关联起来。在你的情况下,它可能是:

interface IDecorate {
  extendedMethod(): number;
}

对于任何需要此装饰器的类,您只需创建一个与该类同名的接口,并让它扩展所有必要的装饰器接口:

@decorate
@anotherDecorator
class MyClass {
  // ...
}

interface MyClass extends IDecorate, IAnotherDecorator {}

现在,只需关闭 ESLint 或 TSLint 对空接口的警告,您就可以开始了。装饰器添加的任何方法或属性现在都可以在装饰类本身中使用。

© www.soinside.com 2019 - 2024. All rights reserved.