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

如何为函数参数生成TypeScript嵌套键类型与动态返回类型?

实现嵌套键路径的动态类型返回函数

完整代码实现

// 生成所有嵌套键路径(点分隔形式)
type NestedKey<S> = S extends object
  ? {
      [K in keyof S & string]: K | `${K}.${NestedKey<S[K]>}`;
    }[keyof S & string]
  : never;

// 根据键路径获取对应嵌套类型
type PathValue<S, K extends NestedKey<S>> = K extends `${infer Key}.${infer Rest}`
  ? Key extends keyof S
    ? PathValue<S[Key], Rest & NestedKey<S[Key]>>
    : never
  : K extends keyof S
  ? S[K]
  : never;

// 定义返回的函数类型(重载形式)
type ReturnFn<S> = {
  (): S;
  <K extends NestedKey<S>>(target: K): PathValue<S, K>;
};

// 实现test函数
function test<S>(data: S): ReturnFn<S> {
  return ((target?: string) => {
    let result: any = data;
    target?.split(".").forEach(k => result = result[k]);
    return result;
  }) as ReturnFn<S>;
}

// 测试示例
const data = {
  suggestion: {a: {nested: true}}
};

const result = test(data);
const fullData = result(); // 类型为 { suggestion: { a: { nested: boolean; }; }; }
const suggestion = result("suggestion"); // 类型为 { a: { nested: boolean; }; }
const suggestionA = result("suggestion.a"); // 类型为 { nested: boolean; }
const nestedValue = result("suggestion.a.nested"); // 类型为 boolean

关键类型解析

NestedKey

递归遍历对象的所有层级,生成所有可能的点分隔键路径联合类型。比如示例中会生成"suggestion"、"suggestion.a"、"suggestion.a.nested"这些字符串字面量。核心逻辑是:

  • 仅处理对象类型的输入;
  • 对每个字符串类型的键,拼接当前键与子对象的嵌套路径,递归生成完整路径;
  • 通过索引访问将所有路径合并为联合类型。

PathValue<S, K>

根据传入的键路径K,从对象S中提取对应位置的类型。核心逻辑是:

  • 用模板字符串类型拆分路径为当前键和剩余路径;
  • 递归处理剩余路径,直到遍历完整个路径,返回最终的类型。

ReturnFn

采用函数重载定义两种调用场景:

  • 无参数调用时,返回原对象类型S;
  • 传入合法嵌套键路径时,返回对应位置的类型。

函数实现说明

函数内部逻辑与你提供的JavaScript逻辑一致,通过可选链和forEach遍历路径节点,最终返回对应的值。使用类型断言将返回值指定为ReturnFn<S>,让TypeScript正确识别函数的重载类型。

内容的提问来源于stack exchange,提问作者Arnaud

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:15:57