包含只读对象的扩展运算符

spread operator for object containing readonly

我的样本class:

class Foo {
  private static counter = 1;

  readonly id: number;

  constructor() {
    this.id = Foo.counter++;
  }
}

我有两个选择:

有没有办法使用传播克隆并保留 readonly(或任何阻止 id 从外部修改的东西)?

Is there anyway to use spread clone AND keep readonly...

没有。 { ...foo } 的结果是一个具有 read/write public 数据属性的普通对象,用于 foo 自己的可枚举属性。您无法在 class 中添加任何内容来改变该行为。

另请注意,由于 { ...foo } 创建了一个普通对象,它将不再是 Foo 的实例。例如,如果 Foo 定义了任何方法,克隆将不会拥有它们。 (在问题的代码中,那种克隆将是 assignment-compatible 和 Foo 因为它 没有 定义任何方法。但是如果 Foo有方法,但不会。)

如果你想使用扩展语法(它不是运算符)来克隆对象,不要使用class,使用interface因为克隆不会继承 class 将分配的原型。

在这种情况下,如您所说,您可以使 Foo 的构造函数可选 copy-constructor:

class Foo {
    private static counter = 1;
  
    readonly id: number;
  
    constructor(other?: Foo) {
        if (other) {
            // Copying
            this.id = other.id; // Just to make TypeScript happy that `id` is
                                // definitely assigned on this path (it would be
                                // anyway, but TypeScript doesn't know that)
            Object.assign(this, other);
        } else {
            // Creating a new one
            this.id = Foo.counter++;
        }
    }
}

(而不是 this.id = other.id; 行,我们 可以 用“明确分配”注释 [readonly id!: number;] 标记 id。但是由于构造函数有多个路径,我不会这样做,因为在修改代码时太容易忘记它。所以我会使用上面不必要的赋值。)