“类”在其自己的类型注释

时间:2018-02-06 10:31:41

标签: typescript dependency-injection

这是基本的DI模​​式:

class Foo {
  foo = 1;
}

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

class Baz extends Foo {}
new Bar(Baz);

它出错了:

  

'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;
  }
}

typeof Foo引用Foo参数类型而不是原始Foo接口:

class Bar {
  constructor(public Foo: number, Quux: typeof Foo) {
    const quux: number = Quux; 
  }
}

1 个答案:

答案 0 :(得分:5)

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

class Foo {
    foo = 1;
}
type FooType = typeof Foo
class Bar {
    constructor(public Foo: FooType) {
    }
}

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

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

修改

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

  

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