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

关于TypeScript递归数组类型声明与嵌套属性导航泛型方法类型约束的技术问询

TypeScript递归数组类型声明与嵌套属性导航泛型方法类型约束的技术问询

嘿,这个需求我太熟了——本质就是要让TypeScript帮你在编译阶段就把嵌套属性路径的合法性校验好,同时实现安全的属性导航对吧?我来给你一步步拆解怎么实现这个泛型方法。

首先核心问题是定义那个someType,也就是能描述所有合法嵌套属性路径的数组类型。我们需要一个递归的类型来遍历对象的每一层属性,生成所有可能的路径组合:

// 递归生成所有合法的嵌套属性路径数组类型
type NestedKeyPath<T> = T extends object
  ? {
      [K in keyof T]: [K] | [K, ...NestedKeyPath<T[K]>]
    }[keyof T]
  : never;

这个类型的逻辑很简单:如果传入的T是对象类型,就遍历它的每个属性K,生成两种路径——要么是单独的[K](对应第一层属性),要么是[K, ...后续嵌套路径](对应深入到下一层的属性);最后通过[keyof T]把所有可能的路径合并成一个联合类型。如果T不是对象,就返回never表示没有合法路径。

接下来就是实现泛型方法了,我们用上面的NestedKeyPath<T>来约束arrayAttr的类型,同时实现属性导航的逻辑:

function navigate<T>(instance: T, arrayAttr: NestedKeyPath<T>): unknown {
  let current: any = instance;
  for (const attr of arrayAttr) {
    current = current[attr];
    // 可以加个运行时兜底,防止属性不存在导致的崩溃
    if (current === undefined) break;
  }
  return current;
}

现在用你给的例子测试一下:

const obj = {
  attribute1: {
    attribute2: {
      attribute3: "value"
    }
  }
};

// 完全合法的调用,返回"value",编译无错误
const result = navigate(obj, ['attribute1', 'attribute2', 'attribute3']);
console.log(result); // 输出 "value"

// 非法调用,编译阶段直接报错!因为'attribute3'不在obj.attribute1的属性列表里
navigate(obj, ['attribute1', 'attribute3']);

不过上面的方法返回类型是unknown,不够优雅。我们可以再写一个递归类型,用来推导路径对应的最终值类型:

// 根据路径推导最终值的类型
type PathValue<T, P extends NestedKeyPath<T>> = 
  P extends [infer K, ...infer Rest]
    ? K extends keyof T
      ? Rest extends NestedKeyPath<T[K]>
        ? PathValue<T[K], Rest>
        : T[K]
      : never
    : T;

然后修改泛型方法,让它能自动推导返回值类型:

function navigate<T, P extends NestedKeyPath<T>>(instance: T, arrayAttr: P): PathValue<T, P> {
  let current: any = instance;
  for (const attr of arrayAttr) {
    current = current[attr];
  }
  return current;
}

现在再调用的话,result的类型会被正确推导成string,完全符合预期:

const result = navigate(obj, ['attribute1', 'attribute2', 'attribute3']);
// result 的类型是 string,不是 unknown

最后补充个小提示:如果你的对象里有可选属性、或者属性值可能是null/undefined,可以调整递归类型来处理这些边界情况,比如在NestedKeyPath里过滤掉可选属性,或者在PathValue里处理null的类型分支。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 07:39:52