查看原文
其他

用于 TypeScript 枚举的实用辅助函数

CUGGZ 前端充电宝 2022-07-21

在 TypeScript 中使用枚举类型时,下面这些辅助函数可能会很有用,赶紧来看一下吧!

辅助函数将以下面的枚举为例进行测试:

enum DayOfWeek {
  Monday = 1,
  Tuesday = 2,
  Wednesday = 3,
  Thursday = 4,
  Friday = 5,
  Saturday = 6,
  Sunday = 7,
}

type Enum = { [s: number]: string };

1检查枚举是否包含某个key

该方法可以用来检查一个枚举中是否包含某个key,代码如下:

function isEnumKey<T extends Enum>(enumSrc: T, key: unknown) : key is keyof T {
    return Number.isInteger(enumSrc[key as keyof T]);
}

测试:

console.log(isEnumKey(DayOfWeek, DayOfWeek[DayOfWeek.Friday])); // true
console.log(isEnumKey(DayOfWeek, DayOfWeek[DayOfWeek.Monday])); // true
console.log(isEnumKey(DayOfWeek, "hello" ));           // false

2检查枚举是否包含某个value

该方法可以用来检查一个枚举中是否包含某个枚举值,代码如下:

function isEnumValue<T extends Enum>(enumSrc: T, value: unknown): value is T[keyof T] {
    return Number.isInteger(enumSrc[enumSrc[value as keyof T] as any as keyof T]);
}

测试:

console.log(isEnumValue(DayOfWeek, DayOfWeek.Friday)); // true
console.log(isEnumValue(DayOfWeek, DayOfWeek.Monday)); // true
console.log(isEnumValue(DayOfWeek, 996)); // false

3将枚举转化为key列表

该方法可以用来将枚举转化为key列表,也就是将所有的枚举key存放在一个数组中,代码如下:

function enumToKeys<T extends Enum>(enumSrc: T): (keyof T)[] {
  return Object.keys(enumSrc).filter((key: keyof T | any) => isEnumKey(enumSrc, key)) as (keyof T)[];
}

测试:

console.log(enumToKeys(DayOfWeek));

输出结果:

[
  'Monday',
  'Tuesday',
  'Wednesday',
  'Thursday',
  'Friday',
  'Saturday',
  'Sunday'
]

4将枚举转化为value列表

该方法可以用来将枚举中所有的枚举值提取出来,放在一个数组中,代码如下:

function enumToValues<T extends Enum>(enumSrc: T): T[keyof T][] {
  return enumToKeys(enumSrc)
    .map((key: keyof T) => enumSrc[key]);
}

测试:

console.log(enumToValues(DayOfWeek));

输出结果:

1234567 ]

5将枚举值转化为对应的key

该方法可以通过枚举值获取枚举中对应的key,代码如下:

function enumValueToKey<T extends Enum>(enumSrc: T, value: T[keyof T]): keyof T | undefined {
  return (enumSrc as any)[value];
}

测试:


console.log(enumValueToKey(DayOfWeek, DayOfWeek.Friday)); // Friday
console.log(enumValueToKey(DayOfWeek, DayOfWeek.Monday)); // Monday
console.log(enumValueToKey(DayOfWeek, 996)); // undefined

6将枚举转换为键值对数组

该方法可以用来将枚举转化为键值对数组,代码如下:

function enumToEntries<T extends Enum>(enumSrc: T): [keyof T, T[keyof T]][] {
  return enumToValues(enumSrc)
    .map((value: T[keyof T]) => 
      [enumValueToKey(enumSrc, value) as keyof T, value]);
}

测试:

console.log(enumToEntries(DayOfWeek));

输出结果:

[
  [ 'Monday'1 ],
  [ 'Tuesday'2 ],
  [ 'Wednesday'3 ],
  [ 'Thursday'4 ],
  [ 'Friday'5 ],
  [ 'Saturday'6 ],
  [ 'Sunday'7 ]
]

7将枚举转换为对象数组

该方法可以用来将枚举转化为对象数组,键值可以自定义,代码如下:

function fromEnum<T extends Enum, C>(
  enumSrc: T,
  projection: (item: [keyof T, T[keyof T]], index: number, array: [keyof T, T[keyof T]][]) => C,
  skip?: (value: [keyof T, T[keyof T]], index: number, array: [keyof T, T[keyof T]][]) => boolean
{
  let entries = enumToEntries(enumSrc);

  if (skip) entries = entries.filter(skip);

  return entries.map(projection);
}

测试:


interface Option<T> {
  label: keyof T;
  value: T[keyof T];
}

const options: Option<typeof DayOfWeek>[] = fromEnum(
  DayOfWeek,
  ([label, value]: [keyof typeof DayOfWeek, DayOfWeek]) => ({
    label,
    value,
  })
);

console.log(options);

输出结果:

[
  { label: 'Monday', value: 1 },
  { label: 'Tuesday', value: 2 },
  { label: 'Wednesday', value: 3 },
  { label: 'Thursday', value: 4 },
  { label: 'Friday', value: 5 },
  { label: 'Saturday', value: 6 },
  { label: 'Sunday', value: 7 }
]


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存