【问题标题】:TypeScript copy existing interface but change type on one propertyTypeScript 复制现有接口但更改一个属性的类型
【发布时间】:2021-09-22 09:05:39
【问题描述】:

我有这个界面:

interface IInternalListener {
  element: HTMLElement,
  id: string,
  type: string,
  listener: EventListenerOrEventListenerObject,
  useCapture: boolean
}

而且我也想用这个接口:

interface IListener {
  element: HTMLElement,
  id: string | number,
  type: string,
  listener: EventListenerOrEventListenerObject,
  useCapture: boolean
}

唯一的区别是id 的类型。我想雇用 DRY(不要重复自己)

如何在没有复制粘贴的情况下创建它。 mapped type 似乎是要走的路,但在这个答案中,他们正在映射所有道具 - Typescript: how do you create a Copy of a type but change the property typeings

我只想改变一个道具。有人知道怎么做吗?我不必使用映射类型,任何可行的解决方案都是公平的游戏。 TIA

【问题讨论】:

  • 为什么不使用泛型类型,其类型参数表示id 的类型?

标签: typescript


【解决方案1】:

有几种方法可以做到这一点。

方式 1

将通用逻辑提取到第三个接口中,其他两个扩展:

interface IWhatever {
  element: HTMLElement,
  type: string,
  listener: EventListenerOrEventListenerObject,
  useCapture: boolean
}

interface IListener extends IWhatever {
  id: string
}

interface IInternalListener extends IWhatever {
  id: string | number
}

方式 2

正如 Robby Cornelissen 在 cmets 中指出的那样,您可以使用泛型:

interface IListener<T> {
  id: T
  element: HTMLElement,
  type: string,
  listener: EventListenerOrEventListenerObject,
  useCapture: boolean
}

方式 3

假设您不拥有 IListener 接口并且无法更改它,但您希望将其中的大部分重用于您的其他接口:

interface IInternalListener extends Omit<IListener, 'id'> {
  id: string | number
}

【讨论】:

  • 谢谢,我觉得这是一个非常有见地的答案,非常感谢
【解决方案2】:

您可以同时使用 extends 和 Omit 实用程序类型。

例子

interface IInternalListener {
  element: HTMLElement,
  id: string,
  type: string,
  listener: EventListenerOrEventListenerObject,
  useCapture: boolean
}

interface IListener extends Omit<IInternalListener, 'id'> {
    id: string | number
}

基本上,我们将删除 id 属性并将其添加回您需要的首选类型。

【讨论】:

    猜你喜欢
    • 2022-06-16
    • 2021-11-18
    • 2021-05-16
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 2022-12-08
    • 2020-06-26
    • 2016-07-18
    相关资源
    最近更新 更多