【问题标题】:Extending Enum in typescript在打字稿中扩展枚举
【发布时间】:2019-03-22 07:11:08
【问题描述】:

我希望在枚举中重用某些值。 有关如何实现此类功能的任何建议。

enum someEnum {
    a = 'Some String',
    b = 2,
};

enum extendedEnum {
    c = 'string',
    b = someEnum.b
}

type someEnumType<T extends someEnum> = T extends someEnum.a ? string :
    T extends someEnum.b ? number : never;

type extendedEnumType<T extends extendedEnum> =
    T extends extendedEnum.c ? string:          // Gives Error
    T extends extendedEnum.b ? number : never;  // Gives Error

【问题讨论】:

  • 请注意,如果您向同一个枚举 enum someEnum { c = 'string', b = someEnum.b } 声明新值,打字稿会将它们合并在一起......但我不建议这样做,因为它会污染原始枚举
  • 不幸的是,作为enum 无法做到这一点,即必须使用type 解决方法之一,根据 TS 项目经理的说法,这不太可能改变。见github.com/microsoft/TypeScript/issues/…

标签: typescript typescript-typings


【解决方案1】:

你可以在你的类型中使用联合:

enum abc {
  a = 1,
  b = 2,
  c = 3
}

enum def {
  d = 4,
  e = 5,
  f = 6
}

type abcdef = abc | def;

let x: abcdef;

x = abc.a;
x = def.d;

【讨论】:

  • 仅当您使用 enum 作为类型而不是值时才有效。
【解决方案2】:

目前,您不能在 TypeScript 中扩展枚举

另一种选择是使用类型:

enum Color1 {
  Red = "Red",
  Green = "Green"
}

enum Color2 {
  Yellow = "Yellow",
  Blue = "Blue"
}

定义一个名为 Colors 的新类型:

type Colors = Color1 | Color2;

然后你可以像下面这样使用它:

public color: Colors;

ngOnInit(): void {
  const Colors = { ...Color2, ...Color1 };
  this.color = Colors.Red; // Colors.Green or Colors.Yellow or Colors.Blue
}

Stackblitz Here

【讨论】:

  • Colors.Red 不起作用。 Colors 不能像枚举一样使用,您会收到错误 ts2693: "'Colors' 仅指一种类型,但在此处用作值。"
  • 合并类型,而不是枚举
【解决方案3】:

我刚刚偶然发现了 2018 年的这篇文章,它解释了如何使用基于字符串的枚举来做到这一点。有关原始评论,请参阅 [1]。

这是一个带注释/果味的版本:

enum someEnum {
  Apple = 'Apple',
  Banana = 'Banana'
}

enum extendedEnum {
  Pear = 'Pear',
  Grape = 'Grape'
}

// The key seems to be to declare a type AND
// a const with the same name

type AllFruits = someEnum | extendedEnum;
const AllFruits = {...someEnum, ...extendedEnum};

let f: AllFruits = AllFruits.Grape;

原始发帖人(他似乎一直是 TypeScript 的贡献者并且知道他们在说什么)提到,使用这种方法,你不能使用像 AllFruits.Grape 这样的东西作为' type literal',这意味着你不能这样做:

// This error will appear: 
// 'AllFruits' only refers to a type, but is being used as a namespace here.

interface FruitBowl {
    fruit: AllFruits.Grape    
}

但这可以通过(一些非常丑陋的东西)来解决:

interface FruitBowl {
    fruit: typeof AllFruits.Grape    
}

我想这是其他人提到的“类型解决方法”之一。

(全部归功于https://github.com/alangpierce) [1]:https://github.com/microsoft/TypeScript/issues/17592#issuecomment-449440944

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-30
    • 2020-01-29
    • 2017-05-09
    • 1970-01-01
    • 2017-03-06
    • 2017-06-08
    • 2020-10-27
    • 1970-01-01
    相关资源
    最近更新 更多