"类"在其自己的类型注释中直接或间接引用

Est*_*ask 3 dependency-injection typescript

这是基本的DI模​​式:

class Foo {
  foo = 1;
}

class Bar {
  constructor(public Foo: typeof Foo) {
    const foo = new Foo();
  }
}

class Baz extends Foo {}
new Bar(Baz);
Run Code Online (Sandbox Code Playgroud)

它给出了一个错误:

'Foo'在其自己的类型注释中直接或间接引用.

但它显然不是自我指涉的,因为它public Foo是属性名称,而且typeof Foo是类型.

这里发生了什么?是否预计将来会解决TypeScript错误?有记录吗?

可以Foo在某种程度上保留属性名称而不重命名它?如此命名是有道理的.


它似乎public Foo: Foo不会产生类型问题,并Foo引用原始Foo接口public AnotherFoo: Foo:

class Bar {
  constructor(public Foo: Foo, public AnotherFoo: Foo) {
    const foo: Foo = AnotherFoo;
    foo.foo;
  }
}
Run Code Online (Sandbox Code Playgroud)

并且 typeof Foo参考Foo参数类型而不是原始Foo界面:

class Bar {
  constructor(public Foo: number, Quux: typeof Foo) {
    const quux: number = Quux; 
  }
}
Run Code Online (Sandbox Code Playgroud)

Tit*_*mir 5

问题是构造函数内部Foo将引用参数而不是类,因此不能Foo仅通过名称引用.执行此操作并保留参数名称的最简单方法是声明类型别名:

class Foo {
    foo = 1;
}
type FooType = typeof Foo
class Bar {
    constructor(public Foo: FooType) {
    }
}
Run Code Online (Sandbox Code Playgroud)

原因Foo : Foo有效但Foo: typeof Foo不起作用是在类型之后:预期类型注释.如果注释是搜索符号时的名称,则只有类型被视为只有它们才有效.

typeof具有类型的符号的名称之后(类,局部变量,参数等).那么搜索必须包含参数,Foo参数在范围内,因此必须考虑.

编辑

@artem提出了一个很好的观点,我没有明确地在上面提到:

[此行为]并非特定于构造函数.在typeof Foo,Foo请参阅范围中指定的最近值(非类型)Foo.一旦你有一个名为的参数Foo,它就在范围内(你甚至可以使用它作为默认值来初始化其他参数),并且它会遮蔽任何名为的外部值.

  • 它不是特定于构造函数.在`typeof Foo`中,Foo引用范围中名为Foo的最近值(不是类型).一旦你有了一个名为Foo的参数,它就在范围内(你甚至可以使用它作为默认值来初始化其他参数),并且它会遮蔽名为`Foo`的任何外部值. (2认同)