从枚举值查找返回枚举

时间:2019-02-07 15:39:55

标签: typescript

我有一个枚举Animals,我正在尝试创建一个接受值的函数,如果有效,整个枚举对象会将值作为emum返回。

enum Animals {
  WOLF = 'wolf',
  BADGER = 'badger',
  CAT = 'cat',
 }

const coerseEnum = <T> (s, E: T): T | undefined => {
  const keys = Object.keys(E);
  const values = keys.map(k => E[k as any]);
  const obj = lodash.zipObject(keys, values);
  const key = lodash.findKey(obj, item => item === s);
  if (!key) return undefined;
  return E[key];
};

const x: Animals | undefined = coerseEnum('cat', Animals);
console.log(x);

但是,它不是强制转换为Animals,而是强制转换为typeof Animals

1 个答案:

答案 0 :(得分:2)

枚举具有枚举项(Animal)的类型,但还具有在运行时保存值的对象的类型。该对象也称为Animal,但是它不是Animal类型的,因为它包含该枚举的所有条目。如果我们从枚举容器对象(typeof Animal)的类型开始回到枚举的类型,我们需要编写typeof Animal[keyof typeof Animal]

在您的情况下,T推断为枚举容器对象typeof Animal,因为这是您要传递给函数的内容。要返回到枚举类型,我们需要做T[keyof T]

enum Animals {
  WOLF = 'wolf',
  BADGER = 'badger',
  CAT = 'cat',
}

const coerseEnum = <T> (s: string, E: T): T[keyof T] | undefined => {
  const keys = Object.keys(E);
  const values = keys.map(k => E[k as any]);
  const obj = lodash.zipObject(keys, values);
  const key = lodash.findKey(obj, item => item === s);
  if (!key) return undefined;
  return E[key];
};

const x: Animals | undefined = coerseEnum('cat', Animals);
console.log(x);

注意 我们通常不会注意到这一点,但是当我们在类型注释中使用Animal时,它是枚举项的类型,当我们使用Animal作为值时,我们正在谈论的是容器对象不是Animal类型。只是想澄清一下,以防上一段不是100%清晰