0

我有一个枚举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);

但是,它不是投射到Animalsbut typeof Animals

4

1 回答 1

3

枚举具有枚举项 ( 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用作值时,我们谈论的是不是 type 的容器对象Animal。只是想澄清一下,以防上一段不是 100% 清楚

于 2019-02-07T15:45:17.117 回答