TypeScript中修改常量对象类型的函数返回值为Promise类型
解决TypeScript中常量函数对象转为Promise返回类型的类型推导问题
问题分析
你需要将一个包含同步/异步函数的常量对象,转换为每个函数都返回对应Promise类型的新对象类型,但当前定义的MyType会导致每个函数的参数和返回值都变成联合类型,无法正确推导单个属性的具体类型。
问题根源
你的MyType使用了泛型参数K并默认设置为所有key的联合类型,在映射时CONST_METHOD_MAP[K]会解析为所有函数类型的联合,导致Parameters<CONST_METHOD_MAP[K]>和ReturnType<CONST_METHOD_MAP[K]>都变成联合类型,最终每个属性的函数签名都被污染成联合类型。
解决方案
我们需要定义一个工具类型来单独处理每个函数的转换,再通过映射类型遍历原对象的每个key,确保每个属性都使用对应函数的具体类型:
1. 定义函数Promise化工具类型
这个工具类型会保留原函数的参数,将返回值统一处理为Promise类型,同时自动解析原返回值为Promise的情况(避免出现Promise<Promise<T>>):
type PromisifyFunction<F extends (...args: any[]) => any> = (...args: Parameters<F>) => Promise<Awaited<ReturnType<F>>>
2. 生成目标对象类型
通过映射类型遍历原常量对象的每个key,为每个属性应用上面的工具类型:
const CONST_METHOD_MAP = { ready: (str: string) => str, b: (num: number) => num, c: () => Promise.resolve(1) } as const type PromisifiedMethodMap = { readonly [K in keyof typeof CONST_METHOD_MAP]: PromisifyFunction<typeof CONST_METHOD_MAP[K]> }
3. 创建符合类型的funcMap
现在你可以基于这个类型创建funcMap,TypeScript会正确推导每个属性的参数和返回值类型:
// 示例实现Web Worker调用逻辑 const funcMap: PromisifiedMethodMap = { ready: (str) => Promise.resolve(str), b: (num) => Promise.resolve(num), c: () => CONST_METHOD_MAP.c() } // 类型推导正确:参数为string,返回Promise<string> funcMap.ready('test').then(res => { // res类型为string }) // 类型推导正确:参数为number,返回Promise<number> funcMap.b(123).then(res => { // res类型为number }) // 类型推导正确:无参数,返回Promise<number> funcMap.c().then(res => { // res类型为number })
效果验证
最终PromisifiedMethodMap的类型完全符合你的期望:
type PromisifiedMethodMap = { readonly ready: (str: string) => Promise<string>; readonly b: (num: number) => Promise<number>; readonly c: () => Promise<number>; }
内容的提问来源于stack exchange,提问作者zaqmjuop
相关产品推荐
相关产品推荐

