我用这些类型设置了一个例子
class IRequest<R>{}
export class ExampleCommandResult{
gg2:string;
}
export class ExampleCommandResult2{
gg:string;
}
export default class ExampleCommand extends IRequest<ExampleCommandResult>{}
type Handler<T extends IRequest<O>, O> = (value: T) => O
然后我将处理程序与ExampleCommandResult2
而非ExampleCommandResult
一起使用
const handler: Handler<ExampleCommand, ExampleCommandResult2> = (v:ExampleCommand) => {
return new ExampleCommandResult2();
}
我期望出现错误,因为ExampleCommand
是IRequest<ExampleCommandResult>
,但是我使用了Handler<ExampleCommand, ExampleCommandResult2>
答案 0 :(得分:0)
您在这里观察到的内容是由于TypeScript使用Structural type system,而不是Nominal type system,而Java正是这种情况。
简而言之,这意味着如果类型的结构相等,即相应类型的每个属性也都是“相等”,则TypeScript认为2个类型相等。
因此,当打字稿解析类型ExampleCommand
时,由于IRequest
和ExampleCommand
都没有属性或方法,因此有效地解析为{}
。因此,不管type参数的值如何,IRequest<R>
的类型都是{}
。
您将看到,一旦开始引入依赖于类型参数R
的方法或属性,就会开始出现错误。因此,如果您要编写以下示例:
class IRequest<R>{
foo: R | null = null;
}
handler
的声明中出现错误,并显示以下错误:
Type 'ExampleCommand' does not satisfy the constraint 'IRequest<ExampleCommandResult2>'.
Types of property 'foo' are incompatible.
Type 'ExampleCommandResult | null' is not assignable to type 'ExampleCommandResult2 | null'.
Property 'gg' is missing in type 'ExampleCommandResult' but required in type 'ExampleCommandResult2'.ts(2344)
001.ts(9, 3): 'gg' is declared here.