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

如何泛化定义含数组属性类的Partial构造函数参数,使元素支持Partial?

通用解决方案:递归深度Partial类型

要实现让类构造函数的Partial类型自动处理数组元素为Partial类型的需求,我们可以定义一个递归的DeepPartial工具类型,它能深度遍历类型结构,将所有层级的对象属性(包括数组元素)转换为可选的Partial类型。

1. 定义通用的DeepPartial工具类型

type DeepPartial<T> = T extends Array<infer U>
  ? Array<DeepPartial<U>>
  : T extends object
  ? { [K in keyof T]?: DeepPartial<T[K]> }
  : T;

这个类型的逻辑是:

  • 如果T是数组类型,就将数组元素转换为DeepPartial<U>(U是数组元素的原始类型)
  • 如果T是对象类型,就将每个属性转换为可选的DeepPartial<T[K]>
  • 基础类型则保持不变

2. 修改类的构造函数参数类型

在需要的类中,用DeepPartial<T>替代原本的Partial<T>,以实现数组元素的Partial支持:

class Foo {
  foo: string;
  constructor({ foo = "foo" }: Partial<Foo> = {}) {
    this.foo = foo;
  }
}

class Bar extends Foo {
  bar: string;
  constructor({ bar = "bar", ...rest }: Partial<Bar> = {}) {
    super(rest);
    this.bar = bar;
  }
}

class Baz {
  bars: Bar[];
  // 使用DeepPartial<Baz>替代Partial<Baz>
  constructor({ bars = [] }: DeepPartial<Baz> = {}) {
    this.bars = bars.map((bar) => new Bar(bar));
  }
}

3. 验证效果

此时传入Foo实例、Bar实例或者直接传入Partial<Bar>对象都不会触发类型错误:

const foo = new Foo();
const bar = new Bar(foo);
const baz1 = new Baz({ bars: [foo] }); // 无报错
const baz2 = new Baz({ bars: [bar] }); // 正常工作
const baz3 = new Baz({ bars: [{ foo: "custom-foo" }] }); // 支持直接传入Partial<Bar>对象

方案优势

这个方案完全通用,不管类的结构有多复杂(比如嵌套对象、多层数组等),DeepPartial都会自动递归处理所有层级的属性,无需手动逐个声明每个数组或嵌套对象的Partial类型,适配性极强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:59:54