枚举的打字稿子集

Ray*_*ach 19 enums typescript

在 Typescript 中,我有一个像这样的枚举

export enum CarBrands {
   Toyota = "TOYOTA"
   Ford = "FORD"
   .....
}
Run Code Online (Sandbox Code Playgroud)

我想像这样创建这个枚举的子集,但似乎无法做到

enum JapaneseCars {
    CarBrands.Toyota
}
Run Code Online (Sandbox Code Playgroud)

或创建一个带有子集的对象

const JapaneseCars = {
    Carbrands.Toyota
}
Run Code Online (Sandbox Code Playgroud)

无论如何,我可以创建一个对象或枚举来使用另一个现有枚举中的值吗?

我无法将 CarBrands 枚举更改为其他数据类型

Mag*_*dor 23

您可以创建一个typeandconst组合,其行为类似于作为另一个枚举的子集的枚举。

缺点:此解决方案强制您让任何enum's 键与其值匹配(或者我还没有找到处理这种情况的解决方案)

// Given an enum
export enum CarBrand {
  TOYOTA = 'TOYOTA',
  FORD = 'FORD',
  PEUGEOT = 'PEUGEOT',
  RENAULT = 'RENAULT'
}

// We can create the type of the subset
export type FrenchCarBrand = Extract<CarBrand, CarBrand.PEUGEOT | CarBrand.RENAULT>;

// And the const that goes with it
export const FrenchCarBrand = {
  [CarBrand.PEUGEOT]: CarBrand.PEUGEOT,
  [CarBrand.RENAULT]: CarBrand.RENAULT
} as const;

// With that you can :

// assign a CarBrand to a FrenchCarBrand ...
const a: FrenchCarBrand = CarBrand.RENAULT;

// ... as long as the CarBrand is in the type
const a_invalid: FrenchCarBrand = CarBrand.TOYOTA; // Type 'CarBrand.TOYOTA' is not assignable to type 'FrenchCarBrand'.

// assign a FrenchCarBrand to a CarBrand ...
const b: CarBrand = FrenchCarBrand.PEUGEOT;

// ... as long as the key exists
const b_invalid: CarBrand = FrenchCarBrand.TOYOTA; // Property 'TOYOTA' does not exist on type 'Readonly<Record<FrenchCarBrand, FrenchCarBrand>>'

// You cannot reassign the value of a FrenchCarBrand ...
FrenchCarBrand.PEUGEOT = CarBrand.RENAULT; // Cannot assign to 'PEUGEOT' because it is a read-only property.

// ... just like you cannot reassign the value of an enum
CarBrand.TOYOTA = 'MAZDA'; // Cannot assign to 'TOYOTA' because it is a read-only property.
Run Code Online (Sandbox Code Playgroud)

如果你想将一个未知的 type 值映射CarBrand到一个 type 的值FrenchCarBrand,它不会工作:

declare const brand: CarBrand;
const frenchBrand: FrenchCarBrand = brand; // Type 'CarBrand' is not assignable to type 'FrenchCarBrand'

// You can use the `as` keyword but it will hide bugs, so I do not recommend at all.
const frenchBrandNoError: FrenchCarBrand = brand as FrenchCarBrand; // No error, but a possible bug in your application.
Run Code Online (Sandbox Code Playgroud)

为此,您需要一个类型保护:

export const isFrenchCarBrand = (brand: CarBrand): brand is FrenchCarBrand => {
  return brand in FrenchCarBrand;
}
Run Code Online (Sandbox Code Playgroud)

它将允许您决定在遇到不需要的值时该怎么做

if (isFrenchCarBrand(brand)) {
  // You can safely assume that `brand` is a `FrenchCarBrand`
} else {
  // `brand` is definitely not a `FrenchCarBrand`
}
Run Code Online (Sandbox Code Playgroud)

我制作了一个TypeScript Playground,显示所有这些代码以及实际的类型检查


gat*_*byz 3

我想你正在寻找这样的东西 -

export enum CarBrands {
  Toyota = "TOYOTA",
  Ford = "FORD"
}

type JapaneseCars = CarBrands.Toyota;

const car: JapaneseCars;
Run Code Online (Sandbox Code Playgroud)

  • @Mikhail Batcer 枚举应该创造真正的价值。在这里,您创建了一个类型,而问题是关于枚举是另一个枚举的子集。 (9认同)
  • 我不明白为什么这个答案得分最低。其实这是最直接的。如果没有 TypeScript 知识的人无法理解,“ JapaneseCars ”可以有几个可能的值:“ type JapaneseCars = CarBrands.Toyota | type JapaneseCars = CarBrands.Toyota | 汽车品牌.日产;` (4认同)