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

如何为异构嵌套对象编写支持多类型返回的类型安全通用取值函数

如何为异构嵌套对象编写支持多类型返回的类型安全通用取值函数

刚好我之前也处理过类似的异构嵌套对象的类型安全取值问题,咱们一步步来拆解和解决你的需求。

首先看你原来的函数,它限定了输入是Record<T, string>——也就是所有属性值都是字符串的对象,但你的实际场景是异构嵌套对象:不同key对应的属性值类型不一样,有的是字符串,有的是嵌套对象。所以核心问题是要让函数能适配任意对象类型,并且准确返回对应key的属性类型,不管这个属性是字符串还是嵌套对象。

基础解决方案:通用泛型函数

我们可以把函数改成两个泛型参数:一个代表输入对象的类型O,另一个代表这个对象的合法keyK(K必须是O的key)。返回值直接定义为O[K],这样TypeScript就能自动推导对应属性的准确类型了。

代码实现如下:

const getConfig = <O extends object, K extends keyof O>(obj: O, key: K): O[K] => {
  return obj[key];
};

测试你的场景

先定义你的对象(如果想让类型更精确,比如key和字符串值都被推断为字面量类型,可以加as const断言):

const obj = {
  keyA: {
    nestedA1: "string",
    nestedA2: "string"
  },
  keyB: {
    nestedB1: {
      doubleNested1: "string",
      doubleNested2: "string"
    }
  }
} as const;

现在测试你想要的用法,完全符合预期:

  • getConfig(obj, "keyA"):返回的类型是{ nestedA1: "string"; nestedA2: "string" },你可以直接链式访问.nestedA1,类型完全安全。
  • getConfig(obj.keyB, "nestedB1"):返回的是{ doubleNested1: "string"; doubleNested2: "string" },同样可以继续访问.doubleNested1。
  • getConfig(obj.keyA, "somethingRandom"):编辑器会直接报编译错误,因为"somethingRandom"不是obj.keyA的合法key。
  • getConfig(obj.keyB.nestedB1, "doubleNested1"):返回的是字符串类型,和你原来的函数效果一致。

扩展:支持一次性获取深层属性(可选)

如果你想一次性传入多层路径(比如keyB.nestedB1.doubleNested1)而不是分多次调用,我们可以用递归泛型实现深层路径的类型推导:

// 定义深层路径的类型:支持"key"或"key.subkey"格式
type DeepKey<T> = T extends object 
  ? keyof T | `${keyof T & string}.${DeepKey<T[keyof T]>}` 
  : never;

// 根据深层路径推导对应的值类型
type DeepValue<T, K extends DeepKey<T>> = K extends keyof T 
  ? T[K]
  : K extends `${infer First}.${infer Rest}`
    ? First extends keyof T
      ? Rest extends DeepKey<T[First]>
        ? DeepValue<T[First], Rest>
        : never
      : never
    : never;

// 实现深层取值函数
const getConfigDeep = <T extends object, K extends DeepKey<T>>(obj: T, key: K): DeepValue<T, K> => {
  const keys = key.split('.') as Array<keyof any>;
  let result: any = obj;
  for (const k of keys) {
    result = result[k];
  }
  return result;
};

用法示例:

// 直接获取深层字符串,类型安全
getConfigDeep(obj, "keyB.nestedB1.doubleNested1");
// 传入错误路径会直接报错
getConfigDeep(obj, "keyB.wrongKey");

这个扩展方案能满足更复杂的深层取值场景,但如果你的需求只是分多次链式访问,基础版本就完全够用了。

备注:内容来源于stack exchange,提问作者Anne

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 14:33:02