You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript泛型调用in定义的映射方法提示参数无法赋值给never类型

报错底层逻辑
  • TypeScript的类型系统不会为未收敛的泛型自动推导「索引访问得到的函数」和「索引对应参数」的关联性。你定义的泛型T extends Text是联合类型'text1' | 'text2'的子类型,TS在处理未指定具体值的泛型时,只会做如下类型推导:
    1. fun[node]的类型是((t: 'text1') => string) | ((t: 'text2') => string)的联合函数类型
    2. 函数参数属于逆变位置,联合类型的函数可接收的参数,需要满足所有成员函数的参数要求,也就是取所有参数类型的交集:'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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 17:45:09