Vyhledávání na webu

typescript - Jak mohu reprezentovat neměnné pole neměnných objektů?


Rád bych definoval třídu, která bere jako jeden ze svých konstrukčních parametrů pole objektů, a rád bych poskytl záruku, že ani pole, ani objekty v něm nebudou upravovány. Můj současný pokus používá modifikátor readonly a generiku Readonly<T> a vypadá přibližně takto:

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;
  }
}

(Odkaz na hřiště.)

Nicméně to způsobí chybu na řádku this.bars=bars;, která říká Typ 'readonly Readonly<Bar>[]' je 'readonly' a nelze jej přiřadit k mutovatelnému typu 'Readonly<Bar>[]'.ts(4104).

Po nějakém hledání jsem našel několik odpovědí, které se zdají, pokud je správně chápu, naznačovat, že proměnné pole a pole readonly/Readonly<T> nelze přiřadit jeden k druhému.

Jak tedy mohu vyjádřit smlouvu o neměnnosti, kterou se snažím vyjádřit? Používám Typescript 4.5.2 a můj tsconfig.json je následující:

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

Odpověď č. 1

Použil bych 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;
  }
}

Ve výrazu readonly bars: ReadonlyArray<Readonly<Bar>> mají jednotlivé části následující význam:

  • readonly uvádí, že vlastnost bars je pouze pro čtení, zabraňuje vám psát this.bars=cokoliv.
  • ReadonlyArray uvádí, že pole je pouze pro čtení, brání vám v zápisu this.bars[0]=cokoliv.
  • Readonly<Bar> uvádí, že prvky pole jsou jen ke čtení, zabraňuje this.bars[0].foo=cokoliv.

Související články