我有一个枚举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
。
答案 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%清晰