TypeScript回调函数类型推断异常问题求助
解决TypeScript中computed函数的自动类型推断问题
问题代码片段
interface Store<T> { value: T } type AnyStore = Store<any> type StoreValue<T> = T extends Store<infer V> ? V : never function computed< V, D extends AnyStore, S extends Store<V> >( createStore: (value: V) => S, depStore: D, compute: (value: StoreValue<D>) => V ): S { return createStore(compute(depStore.value)) } interface MetaStore<T> extends Store<T> { meta: {} } function meta<T>(value: T): MetaStore<T> { return { value, meta: {} } } const depStore: Store<number> = { value: 404 } // 当前类型推断结果:MetaStore<unknown>,预期应为MetaStore<string> const computedStore = computed(meta, depStore, num => `${num}`)
问题现象
- 未显式指定
compute回调的参数类型时,computedStore被推断为MetaStore<unknown>,不符合预期 - 显式指定参数类型(如
(num: number) =>${num}``)时,类型推断正确,得到MetaStore<string>
解决方案
调整computed函数的泛型参数顺序,将依赖的D(依赖Store的类型)放在最前面,让TypeScript优先推断D的类型,再基于它推导V和S:
function computed< D extends AnyStore, // 优先推断依赖Store的类型 V, S extends Store<V> >( createStore: (value: V) => S, depStore: D, compute: (value: StoreValue<D>) => V ): S { return createStore(compute(depStore.value)) }
原理说明
TypeScript的泛型推断是从左到右按顺序进行的。原代码中V在D之前,TypeScript无法先通过depStore推断出D,也就无法用StoreValue<D>确定compute的参数类型,导致V被推断为unknown。
调整泛型顺序后,D先被推断为Store<number>,StoreValue<D>自动解析为number,compute的参数类型明确,V就能正确推断为string,最终S被推导为MetaStore<string>,无需显式指定参数类型。
验证结果
修改后,以下代码的类型推断完全符合预期:
const computedStore = computed(meta, depStore, num => `${num}`) // 推断结果:const computedStore: MetaStore<string>
内容的提问来源于stack exchange,提问作者webdevnsk
相关产品推荐
相关产品推荐

