TypeScript泛型调用in定义的映射方法提示参数无法赋值给never类型
报错底层逻辑
- TypeScript的类型系统不会为未收敛的泛型自动推导「索引访问得到的函数」和「索引对应参数」的关联性。你定义的泛型
T extends Text是联合类型'text1' | 'text2'的子类型,TS在处理未指定具体值的泛型时,只会做如下类型推导:fun[node]的类型是((t: 'text1') => string) | ((t: 'text2') => string)的联合函数类型- 函数参数属于逆变位置,联合类型的函数可接收的参数,需要满足所有成员函数的参数要求,也就是取所有参数类型的交集:
'text1' & 'text2' = never,因此才会出现参数不能赋值给never的报错。
- 当你把泛型替换为具体的
text1或者text2时,类型已经收敛到确定值,TS可以直接匹配到对应函数的参数类型,所以不会报错。
解决方案
方案1:安全的类型断言
你可以直接告诉TS你确认索引对应的函数参数和入参是匹配的,这种方式不会破坏类型安全,写法也最简洁:
function toString1<T extends Text>(node: T): string { return (fun[node] as (item: T) => string)(node); }
对应到业务场景写法如下:
type Role1 = {type: 'role1'} type Role2 = {type: 'role2'} type Roles = { 'role1': Role1; 'role2' : Role2; } function hasPermission<T extends keyof Roles>( role : Roles[T]){ const roleCheck : {[key in keyof Roles]: (role: Roles[key])=> boolean} = { role1 : ( role: Role1) => false, role2 : ( role: Role2) => true, } ; return (roleCheck[role.type] as (role: Roles[T]) => boolean)(role); }
方案2:类型收窄
如果联合类型的项数很少,也可以通过分支判断做类型收窄,TS可以识别每个分支下的具体类型:
function toString1<T extends Text>(node: T): string { if (node === 'text1') return fun[node](node) return fun[node](node) }
内容的提问来源于stack exchange,提问作者Vamshi
相关产品推荐
相关产品推荐

