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

如何修复TypeScript DeepPartial工具类型的可选属性必填问题?

解决DeepPartial工具类型中原有可选属性被强制要求的问题

问题

我需要实现一个DeepPartial<Type, Property>工具类型,要求:

  • 接收对象类型Type作为泛型参数
  • 接收字符串联合类型Property作为指定属性
  • 递归将所有匹配Property的属性设为可选

但当前实现存在问题:原类型中已有的可选属性,在生成的类型中被错误地要求必须存在(仅能赋值undefined),而非保持原有的可选状态。

当前实现代码

export type DeepPartial<Type, Property> = Type extends Array<infer ArrayType>
  ? Array<DeepPartial<ArrayType, Property>>
  : Type extends Record<string, unknown>
    ? {
    [Key in Extract<keyof Type, Property>]?: DeepPartial<Type[Key], Property>;
  } & {
    [Key in Exclude<keyof Type, Property>]: DeepPartial<Type[Key], Property>;
  }
    : Type;

示例与问题复现

定义测试类型:

type Test = {
  a: boolean,
  b: {
    a: 1,
    b: {
      c?: string;
    };
  },
  c?: string;
};

以下代码被TS判定为类型无效(本应合法):

const d: DeepPartial<Test, 'a'> = {b: {b: {}}};

必须显式给原有可选属性赋值undefined才能通过类型检查:

const d: DeepPartial<Test, 'a'> = {b: {b: {c: undefined}}, c: undefined};

问题原因

原实现中,Exclude<keyof Type, Property>会丢失原有属性的可选性信息。用该结果做映射类型时,所有非指定属性都会被强制设为必选,哪怕原属性是可选的。比如原类型中的c?: string,经过映射后变成了必选的string | undefined,因此必须显式赋值。

修复方案

通过Omit<Type, Property>获取非指定属性的类型(保留原可选性),再对其进行递归处理,同时合并指定属性的可选类型:

export type DeepPartial<Type, Property extends PropertyKey> = 
  Type extends Array<infer ArrayType>
    ? Array<DeepPartial<ArrayType, Property>>
    : Type extends object
      ? // 将指定属性设为可选并递归处理类型
        { [K in Extract<keyof Type, Property>]?: DeepPartial<Type[K], Property> } 
        // 保留非指定属性的原可选性,同时递归处理类型
        & { [K in keyof Omit<Type, Property>]: DeepPartial<Type[K], Property> }
        // 展开交叉类型,优化类型显示可读性
        extends infer Merged
        ? { [K in keyof Merged]: Merged[K] }
        : never
      : Type;

验证

修复后的类型可以正确处理原有可选属性:

// 现在这个赋值完全合法
const d: DeepPartial<Test, 'a'> = {b: {b: {}}};

// 以下赋值也依然有效
const e: DeepPartial<Test, 'a'> = {a: true, b: {a: 1, b: {c: 'test'}}, c: 'hello'};
const f: DeepPartial<Test, 'a'> = {c: undefined};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:48:12