调用Immutable.js的fromJS时Type 'string'不可赋值给keyof报错如何解决
报错原因
这个报错是TypeScript函数参数逆变特性导致的:
fromJS定义中要求传入的reviver函数第一个参数key的类型是string | number,也就是可以接收任意字符串/数字类型的key- 你定义的
modelReviver返回的函数第一个参数key的类型是Extract<keyof T, string>,对于User类型来说就是'name' | 'age'字面量类型,接收范围远小于fromJS要求的string | number
TypeScript认为把参数范围更窄的函数赋值给参数范围更宽的函数参数位置会存在类型风险(比如fromJS可能给reviver传一个不在User属性里的key),所以抛出不兼容错误。你之前用Extract限定key类型的操作反而加大了类型不匹配的差异,自然无法解决问题。
解决方法
方案1:调整modelReviver返回函数的参数类型(推荐,类型更安全)
直接让返回的reviver函数参数匹配fromJS的类型要求,在函数内部做类型收窄判断,保证逻辑安全的同时满足类型校验:
export function modelReviver<T>(mapper: Partial<T>): (key: string | number, value: any) => any { return (key, value) => { // 先判断key为字符串,且属于传入mapper的属性 if (typeof key === 'string' && mapper.hasOwnProperty(key)) { return mapper[key as keyof T] } return fromJS(value) }; }
方案2:使用类型断言
如果你确定你的业务场景中fromJS调用reviver时传入的key一定符合Extract<keyof T, string>类型,可以在传参时直接做类型断言绕开校验:
fromJS({}, model as Parameters<typeof fromJS>[1])
内容的提问来源于stack exchange,提问作者deerawan
相关产品推荐
相关产品推荐

