解锁 TypeScript 魔法:递归类型实现字段路径自动推导

先看效果

背景介绍

在开发表单或表格组件时,我们通常需要为 form-item 或 table field 指定字段名,这些字段多为 string 类型。由于缺乏类型校验,字段拼写错误难以及时发现,且手动输入字段名时容易出错,影响开发效率和代码质量。借助 TypeScript 类型系统,我们可以实现字段级的类型安全校验与智能提示,从而提升开发体验并减少潜在的 Bug。

实现思路

  1. JSON 传输的实体类型仅支持基本类型(如 string、number、null、array 及嵌套对象),因此不考虑如 Date、RegExp 等复杂类型。
  2. 字段类型可能存在多层嵌套,因此类型生成需支持递归。
  3. 一般情况下类型不会循环嵌套,但在某些框架(如 Vue 响应式系统)下,类型间可能出现循环引用。因此需对递归深度进行限制,避免类型系统栈溢出。

具体实现

1. 递归深度限制工具类型

为防止递归时出现无限循环,首先实现一个简易的"类型减法"工具,用于每次递归时递减深度计数:

ts 复制代码
/**
 * 递归深度减一的工具类型
 */
type Sub1 = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

示例:

ts 复制代码
type N = 5;
type NSub1 = Sub1[N]; // 4

2. 生成类型路径的递归类型

通过递归遍历对象类型,生成所有可用的字段路径类型:

ts 复制代码
type ValueOf<T> = T[keyof T];
/**
 * 获取对象的所有字段路径
 * @param T - 目标对象类型
 * @param Depth - 递归深度,防止循环引用导致类型系统溢出
 */
type RecordPath<T, Depth extends number = 5> = Depth extends -1
  ? string
  : T extends any[]
    ? `${number}` | `${number}.${RecordPath<T[number], Sub1[Depth]>}`
    : T extends Record<string, any>
      ? ValueOf<{
          [K in keyof T]-?: K extends string
            ? `${K}` | `${K}.${RecordPath<T[K], Sub1[Depth]>}`
            : never
        }>
      : never;
  • 当递归深度耗尽时,兜底类型为 string,防止类型系统报错。
  • 对数组类型单独处理,生成如 xxx.${number}.yyy 的路径类型。
  • 对对象类型递归处理,拼接当前字段名与子字段路径。
  • 将对象的可选属性统一为必选,便于类型推导。

通过上述实现,我们可以在表单或表格开发中,利用 TypeScript 类型系统获得字段路径的智能提示和类型校验,有效避免字段拼写错误,提高开发效率和代码健壮性。

相关推荐
FungLeo7 小时前
成为全栈·React 管理后台篇·总复盘:从“接口能调通”到“后台值得使用”
前端·react.js·前端框架·项目复盘·成为全栈
Csvn9 小时前
并发模式:让渲染学会排队、插队和让路
前端
可乐鸡翅yeah_9 小时前
新手梳理:M3U8 线上问题,哪些是前端锅,哪些是后端锅
前端·ios·音视频·实时音视频·m3u8·音视频在线播放
Flynt9 小时前
Linear 用 1000 个 PR 换掉 styled-components,我写了 200 个按钮,把这笔账复现了一遍
前端·css·preact
JavaGuide10 小时前
NVIDIA 又开源了!这次给 AI Agent 加上权限管控
前端·后端
excel10 小时前
prisma 如何处理数据库竞态
前端·数据库·后端
莪_幻尘11 小时前
Skill 体检:30 个 Skill 全凭感觉?体检器先自曝了 8 个“假 0 分
前端·人工智能·llm
风骏时光牛马12 小时前
AI模型综合能力评测:性能、指令遵循与多场景实测对比
前端
Frag0ut12 小时前
Chrome与Chromium内核浏览器在Windows 11上的新特性全景解析
前端·chrome·windows·web安全·chromium·gemini ai·playready drm
hiahiahia12312 小时前
实现完整 Tool Dispatcher
开发语言·前端