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

如何为TypeScript递归生成类型基于required字段添加可选属性

如何在递归TypeScript类型中根据required字段推断可选属性

问题分析

你当前的GenerateItems类型可根据数组元素生成对应字段类型,但无法依据required标记区分属性的可选性。需要将映射类型拆分为必填和可选两部分,再通过交叉类型合并结果。

解决方案

重构GenerateItems类型,分别处理必填属性与可选属性,最后交叉合并:

type ExpandRecursively<T> = T extends object
  ? T extends infer O ? { [K in keyof O]: ExpandRecursively<O[K]> } : never
  : T;

// 抽离字段类型判断逻辑,避免重复代码
type FieldType<T> = 
  T extends { subFields: infer S extends readonly any[] } 
    ? GenerateItems<S>[]
    : T extends { type: infer Type extends string } 
      ? Type extends "string"
        ? string 
        : Type extends "url"
          ? string
          : Type extends "file"
            ? T extends { allowedFileTypes: infer FT extends readonly string[] }
              ? FT[number]
              : never
            : never
      : never;

type GenerateItems<T extends readonly any[]> = 
  // 处理必填属性:无required或required为true的字段
  {
    [K in keyof T & `${bigint}` as T[K] extends { name: infer N extends string } 
      ? (T[K] extends { required: false } ? never : N) 
      : never
    ]: FieldType<T[K]>
  } & 
  // 处理可选属性:required明确为false的字段
  {
    [K in keyof T & `${bigint}` as T[K] extends { name: infer N extends string } 
      ? (T[K] extends { required: false } ? N : never) 
      : never
    ]?: FieldType<T[K]>
  };

// 测试示例
const items = [
  {
    name: "label",
    type: "string",
    defaultValue: "",
  },
  {
    name: "url",
    type: "url",
    defaultValue: "",
    required: false,
  },
] as const;

type Items = ExpandRecursively<GenerateItems<typeof items>>;
// 生成的类型等价于:
// {
//   label: string;
//   url?: string;
// }

关键说明

  1. 拆分映射逻辑:将原单一映射拆分为两个部分,分别处理必填和可选属性,通过交叉类型&合并最终结果。
  2. 属性筛选规则:
    • 必填属性:筛选required不为false的元素(包括未定义required的默认情况),生成不带?的必填属性。
    • 可选属性:筛选required明确为false的元素,生成带?的可选属性。
  3. 代码复用:将字段类型的判断逻辑抽离为FieldType,避免重复编写递归和类型判断代码。
  4. 递归兼容:保留原有的subFields递归处理逻辑,嵌套字段同样能正确推断可选性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:51:04