TypeScript如何实现手动指定部分泛型 其余泛型从参数自动推导
问题原因
TypeScript 原生不支持泛型参数的部分传入+剩余自动推导:当你显式传入n个泛型参数时,TS会要求你传入所有定义的泛型参数,不会对剩余未传的泛型做自动类型推导,因此会抛出Expected 2 type arguments, but got 1的错误。
避坑提示:不要为了消除报错给需要推导的泛型设置
any/unknown等默认值,这会导致TS放弃对这些泛型位置的类型推导,丢失类型安全。
实现方案
目前社区通用的成熟实现方式有两种,可根据业务场景选择:
方案1:柯里化拆分泛型(最推荐,无冗余参数、类型安全)
将需要手动指定的泛型放在外层函数,需要自动推导的泛型放在内层返回的函数中,利用闭包拆分两层泛型的传入时机:
- 调用外层函数时手动传入需要明确指定的泛型
- 调用内层函数时传入业务参数,TS会自动推导剩余泛型
双泛型简单示例改造
// 原报错写法 // declare function func<T, U> (param: U): T // 改造后 declare function func<T>(): <U>(param: U) => T // 调用方式 const result = func<SomeType>()(value)
三泛型复杂场景改造
// 改造后 function func<T>() { return <U, V>(param1: (param1: U, param2: V) => T, param2: U, param3: V): T => { return param1(param2, param3) } } // 调用方式 const result = func<SomeType>()(value1, value2, value3)
该方案兼容TS 3.0以上所有版本,类型推导完全准确,是目前使用最广泛的实现方式。
方案2:类型标记参数(无额外调用层级)
如果不想增加一层函数调用,可以新增一个无实际运行逻辑的类型标记参数,用来承载需要手动指定的泛型,其余泛型仍然通过入参自动推导:
// 三泛型场景改造 function func<T, U, V>( _typeTag: T, // 仅用于传递类型,运行时无实际作用 param1: (param1: U, param2: V) => T, param2: U, param3: V ): T { return param1(param2, param3) } // 调用方式:传null/undefined加类型断言指定T的类型 const result = func(null as SomeType, value1, value2, value3)
该方案运行时只会多传一个无意义的空值,不会影响实际逻辑,调用时和原写法的参数层级完全一致。
内容的提问来源于stack exchange,提问作者namgold
相关产品推荐
相关产品推荐

