TypeScript联合类型参数被推导为交叉类型报错如何无any解决?
问题根源
当前execute方法的方法名参数和入参参数类型相互独立,TypeScript无法建立两者的关联映射,因此会要求入参必须满足所有方法的参数约束,自动将参数类型推导为TalkInput & WalkInput,因此会抛出缺少对应属性的错误。
解决方案
通过泛型绑定方法名和对应入参、返回值的类型关系,无需使用any,也无需将属性设为可选,即可实现类型安全的调用。
修改后的核心代码如下,仅需要调整execute方法的类型声明:
interface TalkInput { loudness: string; } interface WalkInput { speed: string; } interface PersonResponse<T> { name: string, response: T } interface TalkOutput { mouthMovement: string; } interface WalkOutput { feetMovement: string; } class Person { talk(data: TalkInput): PersonResponse<TalkOutput>{ console.log("talking"); return { name: 'talking', response: { mouthMovement: data.loudness + 'fast' } } } walk(data: WalkInput): PersonResponse<WalkOutput>{ console.log("walking"); return { name: 'walking', response: { feetMovement: data.speed + 'fast' } } } // 泛型绑定方法名和对应的参数、返回值类型 execute<K extends Exclude<keyof Person, 'execute'>>(name: K, data: Parameters<Person[K]>[0]): ReturnType<Person[K]>{ return this[name](data) as ReturnType<Person[K]>; } } const me = new Person(); // 调用时会自动校验入参类型,完全符合预期 me.execute('walk', { speed: 'hello' }); me.execute('talk', { loudness: 'hello' } );
类型说明
- 泛型
K约束为Person类中除execute之外的合法方法名 Parameters<Person[K]>[0]自动提取对应方法的第一个入参类型,实现方法名和入参的类型绑定,调用时传入对应方法名,TS会自动校验入参是否符合该方法的要求ReturnType<Person[K]>自动提取对应方法的返回值类型,无需手动维护返回值的联合类型
该方案扩展性极强,后续如果新增其他类方法,无需修改execute的类型声明,即可自动支持新方法的调用,全程保持类型安全。
内容的提问来源于stack exchange,提问作者Garuuk
相关产品推荐
相关产品推荐

