Pole jen pro čtení
Funkce nedostane vlastní kopii pole, ale totéž pole, které má volající. Může tedy změnit pole, které jí nepatří. Tahle funkce má spočítat lektvary ve vaku a spočítá je správně. Podívejte se ale, jak vak vypadá potom:
const vak = ["Lektvar", "Lano", "Lektvar"];
function spocitejLektvary(predmety: string[]): number {
let pocet = 0;
while (predmety.length > 0) {
if (predmety.pop() === "Lektvar") {
pocet++;
}
}
return pocet;
}
console.log(spocitejLektvary(vak));
console.log(vak);Vypíše:
2
[]pop() z pole odebere poslední prvek, takže po spočítání je vak prázdný. Ve velkém programu se taková chyba hledá těžko: vak se vyprázdní ve funkci, která na první pohled jen počítá. TypeScript tomu dokáže zabránit. Napište před typ pole readonly:
function spocitejLektvary(predmety: readonly string[]): number {main.ts(6,22): error TS2339: Property 'pop' does not exist on type 'readonly string[]'.readonly string[] je pole, které můžete číst, ale ne měnit. Čtení prvku, length, for...of, includes, find, map i filter fungují (map a filter vytvářejí nové pole). Chybí ale push i pop a do prvku nejde přiřadit: predmety[0] = "Meč" skončí chybou Index signature in type 'readonly string[]' only permits reading. (prvky tohoto typu jde jen číst). V parametru je readonly slib, který volající vidí hned v prvním řádku funkce: tahle funkce pole jen čte.
Stejný typ jde napsat i jako ReadonlyArray<string>, podobně jako se string[] dá napsat jako Array<string>. V chybových hláškách TypeScript píše readonly string[].
Obyčejné pole do parametru readonly předat můžete: funkce ho jen čte. Obráceně to nejde. Pole jen pro čtení, třeba seznam vytvořený pomocí as const v lekci Modelování dat, do parametru typu string[] nepředáte, protože taková funkce by ho mohla změnit:
const vsechnaPovolani = ["valecnik", "mag", "hranicar"] as const;
function vypisVsechna(nazvy: string[]): void {
for (const nazev of nazvy) {
console.log(nazev);
}
}
vypisVsechna(vsechnaPovolani);main.ts(9,14): error TS4104: The type 'readonly ["valecnik", "mag", "hranicar"]' is 'readonly' and cannot be assigned to the mutable type 'string[]'.Funkce, která pole jen čte, má proto brát pole readonly: přijme pak obojí. A když má vrátit pole s něčím navíc, vytvoří nové pomocí spreadu: [...predmety, "Stará mapa"].
Pro objekty je tu pomocný typ Readonly<Hrdina>: Hrdina, ve kterém je každá vlastnost jen pro čtení. Je to jako napsat readonly před každou vlastnost, jako v lekci o typech objektů, ale jen tam, kde ho použijete. Parametr hrdina: Readonly<Hrdina> říká, že funkce hrdinu nemění, a hrdina.zivoty = 0 uvnitř ní skončí chybou Cannot assign to 'zivoty' because it is a read-only property. Stejně jako ostatní typy kontroluje readonly jen TypeScript. JavaScript, který se spustí, o něm nic neví.
Typické chyby:
readonlypatří jen před typy s[].readonly Array<string>skončí chybou'readonly' type modifier is only permitted on array and tuple literal types.Napištereadonly string[], neboReadonlyArray<string>.- Funkce s návratovým typem
string[]vrátí přímo svůj parametr:The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type 'string[]'.Vraťte nové pole.
Jak psát:
Pokyny
Funkce sPredmetem má vrátit nový seznam, ale mění ten, který dostane. Změňte typ jejího parametru predmety na readonly string[] a spusťte program: TypeScript ohlásí řádek s push. Tělo funkce nahraďte příkazem return [...predmety, predmet];.
Pod funkcemi vypište sPredmetem(inventar, "Stará mapa") a potom inventar. Inventář se nezměnil:
["Léčivý lektvar", "Lano", "Pochodeň", "Stará mapa"]
["Léčivý lektvar", "Lano", "Pochodeň"]Ani funkce textZivotu nemá hrdinu měnit. Změňte typ jejího parametru na Readonly<Hrdina> a spusťte program. TypeScript ve funkci najde řádek, který hrdinu přece jen mění. Opravte chybu: jedno = hodnotu přiřazuje, a vy chcete porovnávat.
Pod ostatní řádky vypište textZivotu(kira):
Kira: 34/50Začněte programovat zdarma
3/7