javascript - Object.freeze/Object.seal i typescript
Föreslås Object.freeze i Typescript eller finns det något annat sätt att säkerställa att ett objekt förblir oföränderligt?
Eftersom const bara skyddar instansen, men inte egenskaper, är detta uppenbarligen inte ett svar jag letar efter.
Svar #1
finns det ett annat sätt att säkerställa att objektet förblir oföränderligt?
Det beror på vilken försäkringsnivå du vill ha.
Om du vill säkerställa att ingen konsument, vare sig TypeScript- eller JavaScript-kod, kan ändra objektets egenskaper vid körning, är Object.freeze sättet att göra det.
Om kompileringstidkontroller är tillräckliga, till exempel när all konsumentkod garanteras vara enbart TypeScript och typkontrollerad, kan du använda ReadOnly generisk typ, som tar en objekttyp och gör alla egenskaper readonly. Faktum är att Object.freeze() deklareras i bibliotekets typdefinitioner som att den returnerar en ReadOnly-modifierad typ av dess argument:
freeze<T>(o: T): Readonly<T>;
För seal finns det inget sätt att representera ett förseglat objekt i typ-systemet, Object.seal() deklareras för att returnera samma typ som det tar emot:
seal<T>(o: T): T;
och Object.seal() är det enda sättet att gå.
Svar #2
Enklaste lösningen: as const
Detta representerar en djupfrysning av oföränderlighet genom alla nivåer av objekt eller arrayer.
const a = {
b: 1,
c: {d: 'e'},
f: ['g', 'h'],
} as const
Ingen av dessa tillåter överskrivning
a = 'not'
a.b = 'going'
a.c.d = 'to'
a.f[1] = 'change'
All result in error "TS2540: Cannot assign to '<name>' because it is a read-only property."
OBS: Anpassade objekt kanske inte är helt oföränderliga, beroende på hur du har implementerat dem.
Bonus: Om du använder det som en ersättning för enum, kan du lägga till denna rad
type a = typeof a[keyof typeof a]
Oföränderlig parameter med Immutable<>
Detta gör samma sak som as const för att djupfrysa en parameter
// Add this and make it reuseable
type Immutable<T> = {
readonly [K in keyof T]: Immutable<T[K]>
}
Definiera typ inom <>, t.ex. Immutable<MyType>
_method = (a: Immutable<{b:{c:{d:[string]}}}>) => {
// This will complain
a.b.c.d[0] = ""
}
Officiella dokument
