TypeScript参数类型依赖首个参数,调用有效但函数内部无效
解决TypeScript函数内部类型关联收窄问题
问题出在泛型参数A的约束方式上:虽然调用函数时TypeScript能根据传入的action推断出req和res的正确类型,但在函数内部进行条件判断时,TS无法将泛型A的范围收窄到具体的字面量类型,因此req和res始终是所有可能类型的联合,导致访问特定属性时触发类型错误。
解决方案:使用关联联合元组绑定参数类型
把函数参数定义为一组关联的联合元组,让每个action对应的req和res类型强制绑定在一起,这样当通过action进行类型守卫时,TS能自动推断出对应req和res的具体类型。
修改后的代码如下:
interface AddDataRequest { data: any } interface AddDataResponse { id: string } interface ITest { addData(json: AddDataRequest): Promise<AddDataResponse> removeData(json: AddDataResponse): Promise<boolean> } // 定义关联的联合元组类型:每个action对应唯一的req和res类型 type TestInterfaceArgs = { [K in keyof ITest]: [ action: K, req: Parameters<ITest[K]>[0], res: Awaited<ReturnType<ITest[K]>> ] }[keyof ITest] function testInterface(...[action, req, res]: TestInterfaceArgs) { if (action === 'addData') { console.log(res.id); // 现在TS能识别res是AddDataResponse类型 } else if (action === 'removeData') { console.log(req.id); // 现在TS能识别req是AddDataResponse类型 } } testInterface('removeData', { id: 'test123' }, true); // 调用时的类型校验依然正常工作
原理说明
TestInterfaceArgs遍历ITest的所有键,为每个键生成一个包含action、req、res的元组,最后取所有元组的联合类型。- 函数使用剩余参数解构这个联合元组,当判断
action的具体值时,TS会自动将整个元组的类型收窄到对应的成员,从而req和res的类型也会被精准推断。
内容的提问来源于stack exchange,提问作者Kinodegna
相关产品推荐
相关产品推荐

