【问题标题】:How to override type properties in TypeScript如何在 TypeScript 中覆盖类型属性
【发布时间】:2017-08-22 04:13:18
【问题描述】:

例如,我有

type Line = {
  start: Point;
  end: Point;
  color: string; //'cyan'/'aquablue'/...
}

但现在我想在 Line 的基础上创建新的线型,以便将颜色存储为数字:

type HexColorLine = Point & {
  color: number;
}

现在我希望 HexColorPoint 类型等于

{
  start: Point;
  end: Point;
  color: number;
}

但它等于

{
  start: Point;
  end: Point;
  color: string | number;
}

有没有办法覆盖但不扩展prop类型用一些简短的语法?我真的必须为此定义全新的类型吗?

【问题讨论】:

  • 我很确定你不能像你试图做的那样覆盖。您可以改为声明一个不带颜色属性的SimpleLine,然后将Line 和HexColorLine 声明为扩展SimpleLine?有什么原因我想念你不能这样做吗?

标签: typescript


【解决方案1】:

目前不支持此功能。 TypeScript 需要减法类型的概念。提案存在https://github.com/Microsoft/TypeScript/issues/12215 和https://github.com/Microsoft/TypeScript/issues/4183

修复

创建一个基本类型:

type LineBase = {
  start: Point;
  end: Point;
}
type LineBase = LineBase & {
  color: string; //'cyan'/'aquablue'/...
}

【讨论】:

  • 谢谢,这有帮助!我有类型,我需要缩小属性的类型,这很有效。
【解决方案2】:

TL;DR:

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
type Override<T, U> = Omit<T, keyof U> & U

type ColorNumber =  {
  color: number;
}

type HexColorPoint = Override<
  Line,
  ColorNumber
> // --> {start: Point; end: Point; color: number}

我假设你想这样做

type HexColorLine = Line & {
  color: number;
}

而不是

type HexColorLine = Point /* <-- typo? */ & {
  color: number;
}

使用 Typescript >2.8 我能够像这样覆盖:

来自https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html:

我们没有包含 Omit 类型,因为它写得很简单 作为 Pick>.

// So we define Omit -.-
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

// Sidenote: 
// keyof is just getting all the keys for a given type separeted by |
// keyof Line --> 'start' | 'end' | 'color'

// And we define Override which unions the type without unwanted keys and the 
// type defining the new keys
type Override<T, U> = Omit<T, keyof U> & U

// just define which properties you want to redefine 
// and remove "Point &" as it will be done in the Override type
type HexColorLine =  {
  color: number;
}
type HexColorPoint = Override<
  Line,
  HexColorLine
> // --> {start: Point; end: Point; color: number}

【讨论】:

    【解决方案3】:

    创建一个辅助类型:

    type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
    

    用法:

    type HexColorLine = Overwrite<Line, { color: number }>
    

    【讨论】:

    • 这对 TypeScript v3.9 仍然有效吗?
    【解决方案4】:

    从 TypeScript 3.5 开始,一个简单的一次性解决方案可能是:

    type HexColorLine = Omit<Line, 'color'> & {
      color: number;
    }
    

    【讨论】:

      【解决方案5】:

      您可以尝试utility-types 包https://github.com/piotrwitek/utility-types#overwritet-u 中的Override。 因此,将来您可能想从那里使用其他很酷的助手。

      【讨论】:

        猜你喜欢
        • 2020-11-05
        • 2013-04-05
        • 2012-10-17
        • 2018-08-18
        • 2017-05-08
        • 1970-01-01
        • 1970-01-01
        • 2018-08-31
        • 2016-11-06
        相关资源
        最近更新 更多