首页 > 解决方案 > Typescript - 为什么没有相应地强制实现接口

问题描述

我想知道为什么实现两次相同的通用接口但使用不同的参数并不能在派生类中强制执行正确的签名。泛型参数的类型被省略。

请看样例:

interface IEvent { id: number; }
interface IHandle<T> {
  handle(event: T): void;
}

class EmailSentEvent implements IEvent {
  constructor(public id: number, public address: string) {}
}

class UserRegisteredEvent implements IEvent {
  constructor(public id: number) {}
}

class MailHandlerState implements 
  IHandle<EmailSentEvent>, 
  IHandle<UserRegisteredEvent> 
{
  // One implementation is enough to satisfy both interfaces
  handle = (event: EmailSentEvent): void => {

  };
}

沙盒

有没有办法强制执行两个泛型参数?谢谢!

标签: typescripttypescript-generics

解决方案


TLDR:

为了使这项工作,改变方法符号

interface IHandle<T> {
    handle(event: T): void;
}

具有函数类型的属性

interface IHandle<T> {
    handle: (event: T) => void;
}

操场

** 在这种特定情况下,实现仍然可以使用方法语法


事实证明这是按预期工作的:

--strictFunctionTypes以逆变方式而不是双变量方式检查函数类型参数位置的模式。更严格的检查适用于所有函数类型,但源自方法或构造函数声明的函数类型除外。专门排除方法以确保泛型类和接口(例如 Array)继续主要以协变方式相关。严格检查方法的影响将是一个更大的突破性变化,因为大量泛型类型将变得不变(即便如此,我们可能会继续探索这种更严格的模式)

资源

手册中也有


推荐阅读