为什么不编译?
interface ITest { ... }
class Test implements ITest { ... }
class Factory<T extends ITest> {
constructor(private _Test: typeof Test) { }
create(): T {
return new this._Test();
}
}
它提供了Type 'Test' is not assignable to type 'T'. (property) Factory<T extends ITest>._Test: new () => Test
。
我如何才能让它发挥作用
create(): ITest
或通过
private _Test: any
两者都不会真正沟通(代码方式)我所追求的。我能用它做任何事情吗?
答案 0 :(得分:6)
为什么不进行编译?
它没有编译,因为_Test
的类型是typeof Test
。这可能令人困惑,所以让我试着打破它:
打字稿添加&#34;类型&#34;通过javascript的世界为您提供了一种说法&#34;我希望这个对象能够为他们提供所有这些属性和操作。&#34;。从本质上讲,这只是type system所做的。
Typescript具有typeof
运算符,其作用类似type query作为获取&#34;类型&#34;的方式。在类型注释(:
)的右侧使用来自实例化对象。 typeof
为您提供了一种方式来说明&#34;无论该对象具有什么属性和操作,我都想捕获它们并重用它们来检查另一个对象的类型&#34;。
以下是使用此typeof
运算符的示例。
let myObject = {
a: 'a string',
b: 5,
c: false
};
// notice that the `typeof` operator is on the right of the `:`
function takesATypeOfMyObject(obj: typeof myObject) {
// highlight over `a`, `b`, or `c` to see their type
obj.a // (property) a: string
obj.b // (property) b: number
obj.c // (property) c: boolean
}
myObject
是一个普通的javascript对象文字。函数takesATypeOfMyObject
是一个函数,其中一个参数obj
的类型注释为typeof myObject
。该函数表示可以接受与对象myObject
具有相同属性的任何对象。
这不应与只返回字符串的javascript&n; typeof
运算符混淆。打字稿typeof
运算符是其类型系统的一部分。请记住,当typescript编译为javascript时,类型和类型注释就会消失。
要理解的另一个重要事项是打字稿中的类如何工作。课程是一种双刃剑。在打字稿中,类充当两者:
function
中,您可以使用new
调用以获取所提及的类型使用类型注释typeof MyClass
可能很诱人,但这很可能不是您想要的。
考虑以下示例:
// define a class Animal
// this creates the type definition of `Animal` as well as
// the constructor to create an `Animal`
class Animal {
makeNosie() { return 'grrr'; }
}
// use the constructor to create an object of type `Animal`
let myAnimal = new Animal();
// now `myAnimal` has an inferred type of `Animal`
// declare an object to of type `Animal` but instead of using
// the `Animal` constructor, just define an object literal that
// conforms to the type of Animal
let dog: Animal = {
makeNosie: () => 'woof'
};
// the type of dog has been declared explicitly and typescript
// just checks to see if it conforms to the type
所以希望你看到,如果你想让一个对象符合一个类创建的类型,你就不要使用typeof
运算符,你只需说&#34; Animal&#34;,不是typeof Animal
。
但是这给我们带来了一个问题:如果你这样做会怎么样?
请记住,typeof
运算符会尝试捕获要重用的类型。由于class
es定义了一个类型和new
能够创建该类型对象的函数, typeof Animal
实际正在做的是查询Animal的构造函数的类型< /强>
好的,现在我们终于可以深入挖掘您的代码,了解它为什么不编译。以下是您粘贴的原始代码:
interface ITest { } class Test implements ITest { } class Factory<T extends ITest> { constructor(private _Test: typeof Test) { } create(): T { return new this._Test(); } }
查看constructor
的{{1}}。你在这段代码中说的是&#34;我的班级Factory
的{{1}}接受任何符合Test的构造函数的Object。这是一个非常复杂的类型(可能不是你想要的)。
请尝试使用此代码:
constructor
Factory
的类型描述已更改为interface ITest { }
class Test implements ITest { }
class Factory<T extends ITest> {
constructor(private _Test: new() => T) { }
create(): T {
return new this._Test();
}
}
,这表示&#34; Factory的构造函数接受任何返回类型{{_Test
的函数new() => T
1}}&#34;
希望这是你想要的。
我希望我能帮助您解决问题,并向您展示打字稿的强大功能。打字稿试图做一个非常雄心勃勃和疯狂的事情:为任何可能的JavaScript添加完整类型。我认为他们做得很好。