TypeScript泛型:手动指定一个类型参数时如何自动推断另一个?
TypeScript 手动指定部分泛型参数的临时解决方案
问题场景
此前借助Stack Overflow社区帮助,实现了useSearchResults函数根据输入参数自动推断返回类型的逻辑。现在需要手动指定泛型参数M,同时保留S的自动推断能力,但TypeScript不支持仅传入部分泛型参数,触发报错:
Expected 2 type arguments, but got 1.
已知有开源PR计划解决该语法限制,但当前需要在不修改函数返回形式的前提下实现临时兼容。
临时解决方案
方案1:为泛型参数S设置默认类型
修改useSearchResults的泛型定义,给S指定默认类型。调用时仅传入M时,TypeScript会自动用参数推断出的S覆盖默认值,既满足手动指定M的需求,又不影响S的自动推断。
修改后的完整代码:
// 补充原代码中缺失的基础类型定义 type State = Record<string, any>; type SearchResultsState = { // 根据实际业务补充属性,此处为示例 b?: string; }; type StateInitializerFunction<S extends State> = () => S; type StateInitializer<S extends State> = StateInitializerFunction<S> | S; type WidgetInitializer<S extends State> = { state?: StateInitializer<S>; }; type WidgetWrapperResult<S extends State> = { state: S; }; type Model = Record<string, any>; const useSearchResults = <M extends Model, S extends Partial<SearchResultsState> = Partial<SearchResultsState>>( config: WidgetInitializer<S> = {}, ): WidgetWrapperResult<S & Partial<SearchResultsState>> => { const state = typeof config.state === 'function' ? config.state() : config.state || {}; console.log({} as M); // 仅用于在函数中关联M类型 return { state } as any; };
调用示例(可正常运行):
type Product = { id: string; sku: string }; const { state: { a, b } } = useSearchResults<Product>({ state: { a: 1 } }); // 此时M被指定为Product,S被自动推断为{ a: number }
方案2:手动传入S的占位类型
如果方案1不符合业务场景,可在调用时为S传入unknown占位,让TypeScript自动推断实际类型:
type Product = { id: string; sku: string }; const { state: { a, b } } = useSearchResults<Product, unknown>({ state: { a: 1 } });
该方案能解决报错,但代码可读性较差,仅作为备选。
说明
方案1是更优雅的临时兼容方案,利用TypeScript泛型默认值会被实际推断类型覆盖的特性,完美适配当前需求。
内容的提问来源于stack exchange,提问作者inakiabt
相关产品推荐
相关产品推荐

