TypeScript中如何从对象路径获取函数返回类型
实现方案
完全可以实现这个需求,通过TypeScript的递归泛型类型就能自动推断出对应路径的返回值类型,具体步骤如下:
1. 定义合法路径类型
首先实现一个递归类型,用来生成ObjFnc中所有嵌套函数的点分隔路径:
type Path<T> = T extends object ? { [K in keyof T]: `${K & string}${Path<T[K]> extends never ? '' : `.${Path<T[K]>}`}` }[keyof T] : never;
这个类型会遍历对象的所有嵌套属性,生成类似'foo.fnc1'、'foo.fnc2'的合法路径字符串类型,确保传入caller的路径参数只能是有效路径。
2. 定义路径对应的data类型提取工具
接下来写一个工具类型,根据传入的路径,逐层解析到目标函数,提取其返回Promise中data的类型:
type PathToData<T, P extends Path<T>> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? PathToData<T[K], Rest> : never : P extends keyof T ? T[P] extends () => Promise<{ data: infer D; message: string }> ? D : never : never;
这个类型会递归拆分路径字符串,定位到最终的函数,然后通过条件类型提取Promise返回值里的data类型。
3. 实现caller函数
结合上面的类型,实现带有自动类型推断的caller函数:
// 先定义User类型(根据你的需求补充) interface User { name: string; // 其他属性... } // 定义符合ObjFnc类型的实例对象 interface ObjFnc { foo: { fnc1: () => Promise<{ data: string; message: string; }>; fnc2: () => Promise<{ data: number; message: string; }>; }; bar: { fnc3: () => Promise<{ data: User; message: string; }>; }; } const objFnc: ObjFnc = { foo: { fnc1: async () => ({ data: 'test', message: 'success' }), fnc2: async () => ({ data: 123, message: 'success' }), }, bar: { fnc3: async () => ({ data: { name: '张三' }, message: 'success' }), }, }; // 实现caller函数 const caller = <P extends Path<ObjFnc>>(path: P): Promise<PathToData<ObjFnc, P>> => { // 解析路径并定位到目标函数 const pathSegments = path.split('.'); let target: any = objFnc; for (const segment of pathSegments) { target = target[segment]; } // 调用函数并返回data部分 return target().then(res => res.data); };
4. 测试类型推断
现在调用caller时,TypeScript会自动推断返回值的类型:
// foo的类型自动推断为Promise<string> const foo = caller('foo.fnc1'); // num的类型自动推断为Promise<number> const num = caller('foo.fnc2'); // user的类型自动推断为Promise<User> const user = caller('bar.fnc3');
如果需要直接获取非Promise的类型(比如你提到的string),可以使用await:
// 使用await后,foo的类型为string const foo = await caller('foo.fnc1');
内容的提问来源于stack exchange,提问作者lejhbah
相关产品推荐
相关产品推荐

