【问题标题】:In Typescript, can you implement the same generic interface twice, with different generic types?在 Typescript 中,你可以用不同的泛型类型两次实现相同的泛型接口吗?
【发布时间】:2020-01-08 20:14:31
【问题描述】:

我会试着用一个例子来解释我的情况。

假设我有接口:

interface EventListener<TArgs> {
    listen: () => TArgs
}

实现:

class Foo implements EventListener<UserConnectedArgs>, EventListener<UserDisconnectedArgs> {
    listen = (): UserConnectedArgs => {
        // user connection detection logic
    }
    listen = (): UserDisconnectedArgs => {
        // user disconnection detection logic
    }
}

及用法:

const userConnectionListener: EventListener<UserConnectedArgs> = new Foo()
const userDisconnectionListener: EventListener<UserDisconnectedArgs> = new Foo()

我会收到“重复的标识符 'listen'”错误。

如果我错了,请纠正我,但我相信(一般来说)一个类应该能够使用不同的类型多次实现相同的泛型接口,因为它可以为每个类型参数实现不同的行为。

在 C# 中实现相同的概念似乎按我的预期工作,但我知道 C# 在运行时比 Typescript(或 JavaScript)更“类型感知”。

所以我问,你认为我应该怎么做?

提前致谢!

【问题讨论】:

  • 喜欢这个?接口 MyEventListener 扩展 EventListener { 听:() => TArgs }
  • 不,以上是不可能的,因为打字稿中没有“真正的”重载,并且无法在运行时检查泛型类型参数并区分重载。类型在运行时不存在。您需要提供一些运行时值(例如参数)才能根据它“分支”实现
  • 如果UserConnectedArgsUserDisconnectedArgs 是课程,您也可以使用new Foo(UserConnectedArgs) 安排一些内容。如果您需要示例,请告诉我
  • stackoverflow.com/a/13212871/4420812 你可以重载方法,但实现只能是一个。
  • 你不能在一个类中定义两个同名的方法。也许你应该创建两个类并且都实现了接口。

标签: typescript oop


【解决方案1】:

我是打字稿中的泛型新手,所以也许这是错误的......但对我来说,您似乎不需要两个不同的泛型定义:

interface EventListener<Args> {
    listen: () => Args
}

使用不同类型参数的类

class Foo implements EventListener<Args> {
    listen() : Args {
        // the returned "something" value will have type Args
        return something
    }
}

用法

const userConnectionListener: EventListener<UserConnectedArgs> = new Foo()
const userDisconnectionListener: EventListener<UserDisconnectedArgs> = new Foo()


userConnectionListener.listen()      // will return data of type UserConnectedArgs
userDisconnectionListener.listen()   // will return data of type UserDisconnectedArgs

【讨论】:

  • 首先感谢您的回复!虽然,您的解决方案意味着 Foo 必须了解 Args 的每种类型,并为每种类型实现不同的逻辑。相反,知道 Args 可以是 UserConnectedArgs 或 UserDisconnectedArgs 并且仅支持检测这两者(因为它们是您选择实现的)。
  • 是的,您可能需要Foo 中的if 语句来检查您正在处理的参数类型,您不希望这样吗?
  • 是的,if-statements/switch-cases 是我试图避免的事情,目的是让运行时类型系统(如在 C# 中)执行“type-to-method-路由”对我来说。我知道 Typescript 缺少这样的东西,所以我试图找到一种解决方案,尽可能地避免打破 Open-Closed 原则。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多