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

如何在TypeScript中高效创建类的不可变扩展?

更高效的ImmutablePerson实现方案

你可以通过几种方式消除代码冗余,同时满足继承、不可变性和反向类型转换的需求:

方案1:参数属性+Readonly接口约束

利用TypeScript的参数属性减少重复属性声明,同时通过implements Readonly<Person>确保类结构符合只读要求:

class Person {
  id: number;
  name: string;
}

class ImmutablePerson extends Person implements Readonly<Person> {
  constructor(public readonly id: number, public readonly name: string) {
    super();
  }
}

这里参数属性直接在构造函数里完成了属性的声明、初始化和readonly修饰,不需要在类体里重复写id和name字段。implements Readonly<Person>则从类型层面保证了类的属性和只读版Person完全匹配。

方案2:通用不可变子类生成工具

如果需要复用这种“把普通类转成不可变子类”的逻辑,可以写一个通用工具函数,避免重复代码:

type ImmutableConstructor<T> = new (...args: any[]) => Readonly<T>;

function createImmutableClass<T extends new (...args: any[]) => any>(BaseClass: T): ImmutableConstructor<InstanceType<T>> {
  return class extends BaseClass {
    constructor(...args: ConstructorParameters<T>) {
      super(...args);
      Object.freeze(this); // 运行时冻结实例,防止修改
    }

    // 类型层面将所有属性标记为只读
    readonly [K in keyof InstanceType<T>]: InstanceType<T>[K];
  } as unknown as ImmutableConstructor<InstanceType<T>>;
}

// 使用示例
const ImmutablePerson = createImmutableClass(Person);

// 反向转换直接赋值即可,子类实例天然兼容父类类型
const mutablePerson: Person = new ImmutablePerson(1, "Alice");

这个工具会动态生成继承自基类的不可变子类,类型层面通过映射类型把所有属性设为只读,运行时用Object.freeze确保实例无法被修改。

方案3:复用父类构造逻辑

如果父类本身有构造函数,可以直接复用它的逻辑,进一步简化:

class Person {
  constructor(public id: number, public name: string) {}
}

class ImmutablePerson extends Person implements Readonly<Person> {
  constructor(id: number, name: string) {
    super(id, name);
    Object.freeze(this);
  }

  // 类型层面标记属性为只读(可选,因为implements已经约束了类型)
  readonly id: number;
  readonly name: string;
}

// 反向转换示例
const person: Person = new ImmutablePerson(2, "Bob");

关于反向类型转换

ImmutablePerson是Person的子类,TypeScript类型系统天然允许将子类实例赋值给父类类型变量,不需要额外的转换操作——这是面向对象继承的基本特性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:57:10