Generics TypeScript编译器在泛型接口的实现中没有强制类型参数?
考虑一个带有两种实现的TypeScript接口:Generics TypeScript编译器在泛型接口的实现中没有强制类型参数?,generics,typescript,Generics,Typescript,考虑一个带有两种实现的TypeScript接口: interface IFoo {} class FooA implements IFoo {} class FooB implements IFoo {} 接下来,考虑一个通用接口,它接受IFoo作为类型参数的实现: interface IFooHandler<F extends IFoo> { handle(foo: F): string } class FooAHandler implements IFooHandl
interface IFoo {}
class FooA implements IFoo {}
class FooB implements IFoo {}
接下来,考虑一个通用接口,它接受IFoo作为类型参数的实现:
interface IFooHandler<F extends IFoo> {
handle(foo: F): string
}
class FooAHandler implements IFooHandler<FooA> {
handle(foo: FooB): string {
return "Hello, Foo A!";
}
}
使用版本2.0.3中的tsc,这可以完美地编译。所以我的问题是:为什么要编译
注意,我在FooAHandler的handle函数中使用了FooB作为参数类型。我假设这段代码会触发一个编译器错误,因为IFooHandler接口规定handle方法应该接受类型为F的参数,因此,对于IFooHandler,类型为FooA-而不是FooB
我在TypeScript文档中找不到任何关于这种行为的信息。这种行为是故意的吗?如果是,背后的原因是什么?还是我只是用错了这个功能
为了进行比较,在Java中实现完全相同的示例时省略了代码,因为它非常类似,会产生预期的编译错误:
java:1:error FooAHandler不是抽象的,并且不重写IFooHandler中的抽象方法handleFooA
这是因为编译器不按名称比较类型,而是检查它们的结构,并且由于IFoo、FooA和FooB都是空的,所以它们都相等 即使在这样做时:
interface IFoo {
a: string;
}
class FooA implements IFoo {
a: string;
}
class FooB implements IFoo {
a: string;
}
编译器仍然不会抱怨,但一旦我们区分了FooA和FooB:
我们得到编译器错误:
Class 'FooAHandler' incorrectly implements interface 'IFooHandler<FooA>'.
Types of property 'handle' are incompatible.
Type '(foo: FooB) => string' is not assignable to type '(foo: FooA) => string'.
Types of parameters 'foo' and 'foo' are incompatible.
Type 'FooA' is not assignable to type 'FooB'.
Property 'c' is missing in type 'FooA'.
之所以发生这种情况,是因为编译器没有按名称比较类型,而是检查它们的结构,而且由于IFoo、FooA和FooB都是空的,所以它们都相等 即使在这样做时:
interface IFoo {
a: string;
}
class FooA implements IFoo {
a: string;
}
class FooB implements IFoo {
a: string;
}
编译器仍然不会抱怨,但一旦我们区分了FooA和FooB:
我们得到编译器错误:
Class 'FooAHandler' incorrectly implements interface 'IFooHandler<FooA>'.
Types of property 'handle' are incompatible.
Type '(foo: FooB) => string' is not assignable to type '(foo: FooA) => string'.
Types of parameters 'foo' and 'foo' are incompatible.
Type 'FooA' is not assignable to type 'FooB'.
Property 'c' is missing in type 'FooA'.
这在常见问题解答中讨论了好几次,并且基本上是@RyanCavanaugh的副本,谢谢链接。哎哟,我真不敢相信我错过了FAQ中的第一个问题。无论如何,这种行为现在对我来说更有意义了!谢谢你的评论。这在FAQ中讨论了好几次,而且基本上是@RyanCavanaugh的副本,谢谢你的链接。哎哟,我真不敢相信我错过了FAQ中的第一个问题。无论如何,这种行为现在对我来说更有意义了!谢谢你的评论。+1,回答得很好,谢谢!我可能实际上过于简化了我的示例,因为我的实际界面当然不全是空的,但这个答案让我走上了正确的轨道。有没有办法获得最初预期的行为?@Kir最初预期的行为是什么?如果您的意思是希望编译器通过声明的类型而不是结构来比较类型,那么不,这就是ts编译器的工作方式。+1,很好的答案,谢谢!我可能实际上过于简化了我的示例,因为我的实际界面当然不全是空的,但这个答案让我走上了正确的轨道。有没有办法获得最初预期的行为?@Kir最初预期的行为是什么?如果您的意思是希望编译器通过声明的类型而不是结构来比较类型,那么不,这就是ts编译器的工作方式。