TypeScript函数如何提取推断类型参数 解决联合类型返回值报错问题
TypeScript 泛型判别式绑定问题解决方案
报错原因
TypeScript 当前的泛型推断逻辑暂时无法自动关联泛型 T 和对应的 DataType<T> 的绑定关系。构造返回对象时,TS 会将 type 字段推断为联合类型 'a' | 'b',data 字段推断为所有可能值的联合 'x' | 'y' | 'z',二者没有绑定对应关系,自然无法匹配 Input 联合类型的判别式约束。
可行解决方法
方法1:类型断言(最简实现)
逻辑上你已经保证了 type 和 data 的对应关系,直接用类型断言告知 TS 返回值符合 Input 类型即可:
type Input = { type: 'a'; data: 'x' | 'y' } | { type: 'b'; data: 'y' | 'z' } type DataType<T extends Input['type']> = Extract<Input, { type: T }>['data'] export const f = <T extends Input['type']>( type: T, data: DataType<T> ): Input => ({ type, data } as Input)
方法2:函数重载(无断言,类型更严谨)
如果不想使用类型断言,可以通过函数重载明确列出所有合法的入参组合,TS 会自动完成类型校验:
type Input = { type: 'a'; data: 'x' | 'y' } | { type: 'b'; data: 'y' | 'z' } // 重载签名 export function f(type: 'a', data: 'x' | 'y'): Input export function f(type: 'b', data: 'y' | 'z'): Input // 实现签名 export function f( type: Input['type'], data: Input['data'] ): Input { return { type, data } }
方法3:泛型关联完整Input类型(扩展性更强)
如果后续 Input 联合类型会新增更多枚举项,可以直接让泛型约束覆盖完整的 Input 类型,减少后续修改成本:
type Input = { type: 'a'; data: 'x' | 'y' } | { type: 'b'; data: 'y' | 'z' } type ExtractInputByType<T extends Input['type']> = Extract<Input, { type: T }> export const f = <T extends Input['type']>( type: T, data: ExtractInputByType<T>['data'] ): Input => ({ type, data } as Input)
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

