?. a ??

Kontrola undefined pomocí if funguje, ale když chcete jen hodnotu, nebo náhradu za ni, je to hodně kódu:

type Zbran = { nazev: string; poskozeni: number };
type Hrdina = { jmeno: string; zbran?: Zbran };

const kira: Hrdina = { jmeno: "Kira", zbran: { nazev: "Elfí luk", poskozeni: 8 } };
const lena: Hrdina = { jmeno: "Lena" };

let nazevZbrane = "beze zbraně";
if (lena.zbran !== undefined) {
    nazevZbrane = lena.zbran.nazev;
}
console.log(nazevZbrane);

JavaScript má dva operátory, se kterými je to kratší, a TypeScript rozumí oběma.

Operátor volitelného řetězení ?. (anglicky optional chaining) přečte vlastnost, jen když hodnota před ním existuje. lena.zbran?.nazev znamená: když je lena.zbran undefined nebo null, výsledkem je undefined; jinak je to lena.zbran.nazev. Žádný pád programu, žádná chyba:

type Zbran = { nazev: string; poskozeni: number };
type Hrdina = { jmeno: string; zbran?: Zbran };

const kira: Hrdina = { jmeno: "Kira", zbran: { nazev: "Elfí luk", poskozeni: 8 } };
const lena: Hrdina = { jmeno: "Lena" };

console.log(kira.zbran?.nazev);
console.log(lena.zbran?.nazev);

Vypíše:

Elfí luk
undefined

S obyčejnou tečkou, lena.zbran.nazev, by TypeScript ohlásil error TS18048: 'lena.zbran' is possibly 'undefined'. Ví také, že výsledek ?. může chybět: lena.zbran?.nazev je typu string | undefined.

Operátor ?? (anglicky nullish coalescing) dává náhradu za chybějící hodnotu. a ?? b je a, pokud a není null ani undefined; jinak je to b. Oba operátory se spolu dobře doplňují:

console.log(kira.zbran?.nazev ?? "beze zbraně");
console.log(lena.zbran?.nazev ?? "beze zbraně");

Vypíše:

Elfí luk
beze zbraně

Výraz lena.zbran?.nazev ?? "beze zbraně" je prostě typu string: TypeScript ví, že ?? chybějící případ doplnil. Můžete ho uložit do proměnné typu string nebo vrátit z funkce, která vrací string. Bez ?? by byl return takové funkce chyba: Type 'string | undefined' is not assignable to type 'string'.

Někdy uvidíte, že se k náhradě používá i ||. Kromě true a false funguje a || b s jakýmikoli hodnotami: dá a, když se a počítá jako pravda, a jinak b. Jenže 0 a prázdný text "" se počítají jako nepravda, takže || nahradí i je, kdežto ?? nahradí jen null a undefined. U čísel je ten rozdíl důležitý:

const sipy = 0;
console.log(sipy || 10);
console.log(sipy ?? 10);

Vypíše:

10
0

Hrdina, kterému došly šípy, má 0 šípů, ne 10. Když myslíte „pokud chybí“, použijte ??.

Typická chyba: ?. na špatném místě. Patří hned za hodnotu, která může chybět: lena.zbran?.nazev, protože nepovinná je zbran. lena?.zbran.nazev kontroluje lena, která existuje vždycky, a TypeScript dál hlásí 'lena.zbran' is possibly 'undefined'.

Pokyny

Lena nemá zbraň, a tak TypeScript hlásí hrdina.zbran.nazev. Opravte řádek pomocí ?. a ??, aby hrdina beze zbraně dostal text beze zbraně. Program pak vypíše:

Kira: Elfí luk
Bruno: Válečná sekera
Lena: beze zbraně

Ke každému řádku přidejte poškození zbraně. Hrdina beze zbraně bojuje holýma rukama s poškozením 1: použijte znovu ?. a ??. Program pak vypíše:

Kira: Elfí luk (poškození 8)
Bruno: Válečná sekera (poškození 11)
Lena: beze zbraně (poškození 1)

Sečtěte poškození všech hrdinů (zase s 1 za holé ruce) a za cyklem vypište součet. Program pak vypíše:

Kira: Elfí luk (poškození 8)
Bruno: Válečná sekera (poškození 11)
Lena: beze zbraně (poškození 1)
Celkové poškození: 20

Začněte programovat zdarma

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

6/10