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

如何在TypeScript中深度遍历对象并断言其类型?

可行实现方案:基于属性路径的类型断言工具

我们可以通过通用路径解析+类型守卫的组合来实现你要的功能,既消除嵌套断言,又保留TypeScript的类型安全。下面是具体实现步骤:

1. 定义路径解析的工具类型

先实现两个核心类型,让TypeScript能自动推导属性路径对应的目标类型,确保路径合法性:

// 提取对象的所有可嵌套属性路径
type Path<T> = T extends object
  ? { [K in keyof T]: K extends string | number ? `${K}` | `${K}.${Path<T[K]>}` : never }[keyof T]
  : never;

// 根据路径获取对应的目标类型
type PathValue<T, P extends Path<T>> = P extends `${infer K}.${infer Rest}`
  ? K extends keyof T
    ? Rest extends Path<T[K]>
      ? PathValue<T[K], Rest>
      : never
    : never
  : P extends keyof T
  ? T[P]
  : never;

2. 实现运行时路径检查的通用函数

写一个底层函数负责逐层解析路径,再封装断言逻辑:

function getPathValue<T, P extends Path<T>>(obj: T, path: P): PathValue<T, P> | undefined {
  return path.split('.').reduce((current, key) => {
    if (current == null || typeof current !== 'object') return undefined;
    return (current as Record<string, unknown>)[key];
  }, obj as unknown) as PathValue<T, P> | undefined;
}

function assertPath<T, P extends Path<T>>(
  obj: T,
  path: P,
  validator?: (value: PathValue<T, P>) => boolean
): asserts obj is T & { [K in P]: NonNullable<PathValue<T, P>> } {
  const value = getPathValue(obj, path);
  if (value == null || (validator && !validator(value))) {
    throw new Error(`路径 ${path} 不存在或不符合规则`);
  }
}

3. 封装你的assertUUID专属函数

基于通用逻辑,封装UUID格式的校验断言:

// UUID格式校验正则
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

function assertUUID<T, P extends Path<T>>(
  obj: T,
  path: P
): asserts obj is T & { [K in P]: string } {
  assertPath(obj, path, (value) => {
    return typeof value === 'string' && UUID_REGEX.test(value);
  });
}

这个函数会一次性完成:路径存在性检查、非空校验、UUID格式验证,断言失败直接抛出错误。

4. 实际用法对比

原来的冗余写法:

// 嵌套条件+类型断言
if (effect?.language?.effect?.id?.effect) {
  const uuid = effect.language.effect.id.effect as string;
  // 还要额外写UUID格式校验
}

新的简化写法:

// 一行完成所有校验
assertUUID(effect, 'language.effect.id.effect');
// 断言后TypeScript自动识别该属性为合法UUID字符串
const uuid = effect.language.effect.id.effect;

额外优势

因为有Path<T>类型的支持,调用assertUUID时TypeScript会自动提示合法的属性路径,避免拼写错误,大幅提升开发效率。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:17:27