Hvorfor kan jeg ikke gøre et array skrivebeskyttet på denne måde i TypeScript?


Dokumentationen viser (#ReadOnlyArray) hvordan man gør det ved hjælp af et interface, men da jeg udforsker sproget, spekulerede jeg på, hvorfor dette ikke også fungerer?

type TraverseTuple<T extends Array<unknown>> = {
     readonly [P in keyof T]: T[P];
}

const test: TraverseTuple<[string, number, string, number]> = ['s', 1, 'o', 2];

test[1] = 0; // not readonly !

Svar #1

Der er en indbygget skrivebeskyttet array-type, som gør arrays skrivebeskyttede (medmindre de tilbageføres til et almindeligt array).

const test: ReadonlyArray<string|number> = ['s', 1, 'o', 2];

test[1] = 0;

Men for tuples skal du oprette en eksplicit type, sådan her:

const test: Readonly<{ 0: string, 1: number, 2: string, 3: number }> = ['s', 1, 'o', 2];

test[1] = 1;

Svar #2

Denne opførsel understøttes specifikt ikke. Muligheden for at mappe tupler blev først for nylig introduceret til TypeScript 3.1 med denne PR. Fra PR'en:

En readonly, -readonly eller +readonly-annotation i en homomorf kortlagt type har i øjeblikket ingen effekt på array- eller tuple-elementer (vi kunne overveje at kortlægge fra Array til ReadonlyArray og omvendt, selvom det teknisk set ikke bevarer strukturen, fordi det tilføjer eller fjerner metoder).

Relaterede artikler