可通过条件类型配合 infer、递归映射和分布式处理,在编译期从复杂 JSON 结构中静态提取精确类型契约,核心是结构特征逻辑推导而非运行时解析。

可以通过条件类型配合 infer、递归映射和分布式处理,从复杂 JSON 结构(如 OpenAPI Schema 或运行时对象)中静态提取出精确的类型契约。核心不在于“运行时解析”,而是在编译期基于结构特征做逻辑推导。
用条件类型识别并解包嵌套结构
当面对形如 { data: { user: { id: 1, name: "Alice" } }, meta: { ok: true } } 的响应时,可定义条件类型逐层提取:
- 用
T extends { data: infer D } ? D : never提取data字段类型 - 再对
D做二次判断:D extends { user: infer U } ? U : never,得到用户子结构 - 结合
keyof和映射类型,自动为每个键生成对应类型描述,例如{ [K in keyof T]: TypeName<t> }</t>
处理联合与可选字段的类型收窄
真实 JSON 常含可选字段("status"?: "idle" | "loading" | "error")或多态字段("payload": string | number | object)。这时需借助分布式条件类型:
-
type FlattenUnion<t> = T extends any ? { [K in keyof T]: T[K] } : never</t>—— 利用联合类型的自动分发,确保每个分支单独处理 - 对可选属性,用
Required<Pick<T, K>>+Partial<Omit<T, K>>拆解后重组,保留原意 - 对
payload这类多态字段,可用Extract<T["payload"], object>单独提取对象分支
对接 OpenAPI Schema 实现端到端契约生成
OpenAPI 中的 allOf、anyOf、oneOf 可直接映射为 TypeScript 的交叉(&)、联合(|)或排他联合类型。工具如 openapi-typescript 内部正是靠条件类型完成这一转换:
-
allOf: [{ $ref: "#/components/schemas/User" }, { $ref: "#/components/schemas/Timestamped" }]→ 生成User & Timestamped -
anyOf: [{ type: "string" }, { type: "number" }]→ 推导为string | number - 对
schema.properties的遍历,则通过递归条件类型展开每一层type、items、additionalProperties
从字面量值反推契约(as const + infer)
若已有运行时 JSON 示例(如配置对象),可通过 as const 锁定字面量类型,再用条件类型提取结构:
-
const config = { timeout: 5000, retries: 3, enabled: true } as const→ 类型为精确字面量对象 - 定义
type KeysOf<t> = keyof T</t>,再用type ValuesOf<t> = T[keyof T]</t>获取所有值类型集合 - 配合
infer解构数组:type First<t extends any> = T extends [infer F, ...any[]] ? F : never</t>,可用于解析请求体中的固定顺序字段


















