TypeScript无法依据参数推断类型?两种实现方案遇阻
TypeScript 参数类型关联问题解决
我尝试根据第一个参数的取值限制第二个参数的可选类型,但未能成功,以下是两种尝试方案及遇到的问题:
方案一:函数重载
export function printProfileByType( type: 't1', payload: { name: string } ): string; export function printProfileByType( type: 't2', payload: { age: number } ): string; export function printProfileByType( type: 't1' | 't2', payload: { name: string } | { age: number } ): string { if (type === 't1') { console.log(payload.name); // 错误:Property 'name' does not exist on type '{ name: string; } | { age: number; }'. Property 'name' does not exist on type '{ age: number; }' } return ''; }
即便添加了if (type === 't1')的判断,TypeScript仍无法确定payload必然是{name: string}类型。
方案二:泛型
type FunctionParams = { t1: { name: string }; t2: { age: number }; }; export function PrintName<T extends keyof FunctionParams>( type: T, payload: FunctionParams[T] ) { if (type === 't1') { console.log(payload.name); // 错误:Property 'name' does not exist on type '{ name: string; } | { age: number; }'. Property 'name' does not exist on type '{ age: number; }' } else if (type === 't2') { console.log(payload.age); // 错误:Property 'age' does not exist on type '{ name: string; } | { age: number; }'. Property 'age' does not exist on type '{ name: string; }'. } }
用泛型绑定参数关系后,同样遇到类型收窄失败的问题。
解决方法
核心问题是TypeScript无法自动将type的判断逻辑和payload的类型做关联收窄,以下是几种可行的解决方式:
方法1:使用可辨识联合类型(推荐)
把两个参数封装成一个对象,通过type字段作为辨识符,让TypeScript自动识别参数间的绑定关系:
type ProfileParams = | { type: 't1'; payload: { name: string } } | { type: 't2'; payload: { age: number } }; export function printProfile(params: ProfileParams): string { if (params.type === 't1') { console.log(params.payload.name); // 正确识别为{ name: string }类型 } else { console.log(params.payload.age); // 正确识别为{ age: number }类型 } return ''; }
方法2:泛型函数中添加类型断言
如果不想修改参数结构,可以在判断后手动添加类型断言,明确payload的类型:
type FunctionParams = { t1: { name: string }; t2: { age: number }; }; export function PrintName<T extends keyof FunctionParams>( type: T, payload: FunctionParams[T] ) { if (type === 't1') { console.log((payload as FunctionParams['t1']).name); } else if (type === 't2') { console.log((payload as FunctionParams['t2']).age); } }
方法3:优化重载函数的实现体
在重载函数的实现体中,对payload额外做字段存在性判断,帮助TypeScript完成类型收窄:
export function printProfileByType( type: 't1', payload: { name: string } ): string; export function printProfileByType( type: 't2', payload: { age: number } ): string; export function printProfileByType( type: 't1' | 't2', payload: { name: string } | { age: number } ): string { if (type === 't1' && 'name' in payload) { console.log(payload.name); } return ''; }
内容的提问来源于stack exchange,提问作者Isaac
相关产品推荐
相关产品推荐

