在泛型中使用错误类型时出现预期错误

时间:2019-08-01 15:16:31

标签: typescript

我用这些类型设置了一个例子

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();
}

我期望出现错误,因为ExampleCommandIRequest<ExampleCommandResult>,但是我使用了Handler<ExampleCommand, ExampleCommandResult2>

1 个答案:

答案 0 :(得分:0)

您在这里观察到的内容是由于TypeScript使用Structural type system,而不是Nominal type system,而Java正是这种情况。

简而言之,这意味着如果类型的结构相等,即相应类型的每个属性也都是“相等”,则TypeScript认为2个类型相等。

因此,当打字稿解析类型ExampleCommand时,由于IRequestExampleCommand都没有属性或方法,因此有效地解析为{}。因此,不管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.