TypeScript泛型函数与索引访问报错问题求助
TypeScript泛型关联类型报错解决方法
问题代码
interface A { value1: string; value2: string; func(a: string, b: string): void; } interface B { value1: number; value2: number; func(a: number, b: number): void; } function Outer <T extends A | B>(myFunc: T['func'], a: T['value1'], b: T['value2']) { myFunc(a, b); // 报错:Argument of type 'string | number' is not assignable to parameter of type 'never'. }
错误原因
TypeScript无法将myFunc的参数类型和a、b的类型做关联推断。当T是A | B的联合类型时,T['func']会变成两个函数类型的联合,T['value1']和T['value2']则是string | number的联合。而联合类型的函数只有在参数是所有分支参数的交集时才能被调用,string和number的交集是never,因此触发报错。
解决方法
方法1:使用函数重载
直接为Outer定义针对A和B的重载,让TypeScript精准匹配参数类型:
interface A { value1: string; value2: string; func(a: string, b: string): void; } interface B { value1: number; value2: number; func(a: number, b: number): void; } // 重载签名 function Outer(myFunc: A['func'], a: A['value1'], b: A['value2']): void; function Outer(myFunc: B['func'], a: B['value1'], b: B['value2']): void; // 实现签名 function Outer(myFunc: any, a: string | number, b: string | number) { myFunc(a, b); } // 调用示例 Outer((a,b)=>console.log(a+b), "hello", "world"); // 自动推断为A类型 Outer((a,b)=>console.log(a+b), 1, 2); // 自动推断为B类型
方法2:参数打包为关联对象(更适配React Hook场景)
把myFunc、a、b打包成符合A或B的对象,让TypeScript通过对象整体类型关联所有成员,这也符合React Hook常用的配置对象传参风格:
interface A { value1: string; value2: string; func(a: string, b: string): void; } interface B { value1: number; value2: number; func(a: number, b: number): void; } function Outer<T extends A | B>(props: Pick<T, 'func' | 'value1' | 'value2'>) { props.func(props.value1, props.value2); // 无类型报错 } // 调用示例 Outer({ func: (a,b)=>console.log(a+b), value1: "hello", value2: "world" }); Outer({ func: (a,b)=>console.log(a+b), value1: 1, value2: 2 });
内容的提问来源于stack exchange,提问作者Jackson
相关产品推荐
相关产品推荐

