【问题标题】:How can I represent an immutable array of immutable objects?如何表示不可变对象的不可变数组?
【发布时间】:2021-11-26 06:05:54
【问题描述】:

我想定义一个类,它将对象数组作为其构造函数参数之一,并且我想保证数组和其中的对象都不会被修改。我目前的尝试使用readonly 修饰符和Readonly<T> 泛型,看起来像这样:

export type Foo = { foo: string };

export class Bar {
  readonly foo: Foo;
  readonly bars: Array<Readonly<Bar>>;

  constructor(
    foo: Readonly<Foo>,
    bars: Readonly<Array<Readonly<Bar>>>,
  ) {
    this.foo = foo;
    this.bars = bars;
  }
}

(Playground link.)

但是,这会在this.bars = bars; 行出现错误,说The type 'readonly Readonly&lt;Bar&gt;[]' is 'readonly' and cannot be assigned to the mutable type 'Readonly&lt;Bar&gt;[]'.ts(4104)

经过一番搜索,我找到了answers 中的couple,如果我理解正确的话,这似乎表明可变数组和readonly/Readonly&lt;T&gt; 数组不能相互分配。

那么,我如何表示我试图表达的不变性契约?我使用的是 Typescript 4.5.2,我的tsconfig.json 如下:

{
  "compilerOptions": {
    "exactOptionalPropertyTypes": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noUncheckedIndexedAccess": true,
    "strict": true
  }
}

【问题讨论】:

标签: typescript


【解决方案1】:

我会使用ReadonlyArray

export type Foo = { foo: string };

export class Bar {
  readonly foo: Foo;
  readonly bars: ReadonlyArray<Readonly<Bar>>;

  constructor(
    foo: Readonly<Foo>,
    bars: ReadonlyArray<Readonly<Bar>>,
  ) {
    this.foo = foo;
    this.bars = bars;
  }
}

语句readonly bars: ReadonlyArray&lt;Readonly&lt;Bar&gt;&gt;中,不同部分的含义如下:

  • readonly 声明 bars 属性是只读的,它会阻止您写入 this.bars = whatever
  • ReadonlyArray 声明该数组是只读的,它会阻止您写入 this.bars[0] = whatever
  • Readonly&lt;Bar&gt; 声明数组的元素是只读的,它阻止了this.bars[0].foo = whatever

【讨论】:

  • 嗯,你甚至可以用一个可变数组来调用它(例如new Bar({foo:'foo'}, []))。太好了,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 2021-03-20
  • 1970-01-01
  • 2011-01-14
相关资源
最近更新 更多