You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 23:27:28