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)
问题是构造函数内部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,它就在范围内(你甚至可以使用它作为默认值来初始化其他参数),并且它会遮蔽任何名为的外部值.