我很困惑为什么有时我的类型保护功能不起作用。
例如,我有下面的类型保护函数。
enum Services {
email = 'Email',
cloud = 'Cloud',
map = 'Map',
}
// this is ok.
const isValidService = (value: string): value is keyof typeof Services => {
return value in Services;
}
// this doesn't work.
const isKeyOfEnum = <T>(enumObject: T) => (value: string): value is keyof typeof T => value in enumObject;
并在下面的代码中使用它们
const handleServicesChange = useCallback((item: string) => {
if (isValidService(item)) {
// type of item is judged as 'email' | 'cloud' | 'map'
console.log(Services[item]);
}
}, []);
const handleServicesChange = useCallback((item: string) => {
const isServiceKey = isKeyOfEnum(Services);
if (isServiceKey(item)) {
// type of item still be judged as string ...
console.log(Services[item]);
}
}, []);
那么为什么KeyOfEnum不能工作呢?如何重构它呢?
2条答案
按热度按时间inb24sb21#
这里有几件事:
首先-
T
是一个类型,所以TS报告typeof T
试图使用类型作为值。只需使用T
,而不是typeof T
。TS然后报告
Type 'keyof T' is not assignable to type 'string'
。您的输入始终是string
,但Assert的返回类型实际上将其削弱为string | number | symbol
。好吧,只需将Assert的类型缩小为Extract<keyof T, string>
。最后,
value in enumObject
显示一个错误:Type 'T' is not assignable to type 'object'. This type parameter might need an
extends objectconstraint.
很好,只需在T
上添加建议的类型约束。把它们放在一起,你会得到:
Playground
rxztt3cl2#
T
已经是类型,一个泛型类型,所以value
应该是keyof T
而不是keyof typeof T
keyof运算符接受一个对象类型,并生成其键的字符串或数字文本并集。