Generické typy

Generické můžou být i vaše vlastní typy. Obchod prodává krabice. Každá má štítek, ale uvnitř je pokaždé něco jiného: mince, šípy, meč. Místo typu pro každý druh krabice deklarujte jeden typ s typovým parametrem:

type Krabice<T> = { stitek: string; obsah: T };

Typový parametr se píše do špičatých závorek za název typu a uvnitř typu se T používá jako kterýkoli jiný typ. Krabice<number> je pak { stitek: string; obsah: number } a Krabice<string[]> je krabice s texty. TypeScript kontroluje obsah podle typového argumentu:

type Krabice<T> = { stitek: string; obsah: T };

const mince: Krabice<number> = { stitek: "Mince", obsah: 50 };
const sipy: Krabice<string[]> = { stitek: "Šípy", obsah: ["Ohnivý šíp", "Ledový šíp"] };
const mec: Krabice<number> = { stitek: "Meč", obsah: "Stříbrný meč" };

TypeScript ohlásí:

main.ts(5,47): error TS2322: Type 'string' is not assignable to type 'number'.

Krabice mec tvrdí, že obsahuje číslo. U proměnné typový argument píšete vždycky. Bez něj by const mec: Krabice = … skončilo chybou Generic type 'Krabice' requires 1 type argument(s). (TS2314), stejně jako u Array.

Typové parametry můžou mít i rozhraní a typ jich může mít několik:

interface Police<T> {
    nazev: string;
    veci: T[];
}

type Dvojice<A, B> = [A, B];

const policeLektvaru: Police<string> = { nazev: "Lektvary", veci: ["Léčivý lektvar", "Elixír"] };
const cenovka: Dvojice<string, number> = ["Stříbrný meč", 120];

Generické typy v generických funkcích. Funkce, která přijme jakoukoli krabici, je také generická:

type Krabice<T> = { stitek: string; obsah: T };

function vybal<T>(krabice: Krabice<T>): T {
    console.log(`Vybaluji: ${krabice.stitek}`);
    return krabice.obsah;
}

const mince: Krabice<number> = { stitek: "Mince", obsah: 50 };
const zlato = vybal(mince) + 20;
console.log(zlato);

Vypíše:

Vybaluji: Mince
70

Ve volání vybal(mince) TypeScript vidí, že mince je Krabice<number>, takže T je number a vybal vrátí číslo: přičíst k němu 20 je v pořádku. Pro Krabice<string[]> by vrátila string[].

Pokyny

Deklarujte generický typ Truhla<T> pro truhlu s vlastností misto (text) a vlastností korist typu T. Pak vytvořte dvě truhly: truhlaZlata typu Truhla<number> na místě "Skřetí jeskyně" s kořistí 120 a truhlaLektvaru typu Truhla<string[]> na místě "Věž čaroděje" s kořistí ["Léčivý lektvar", "Elixír"].

Napište generickou funkci otevriTruhlu<T>(truhla: Truhla<T>): T. Ta vypíše Otevírám truhlu: a místo, kde truhla stojí, třeba Otevírám truhlu: Skřetí jeskyně, a vrátí kořist z truhly.

Kira otevře obě truhly. Na konec programu přidejte tyto řádky:

zlato = zlato + otevriTruhlu(truhlaZlata);
for (const lektvar of otevriTruhlu(truhlaLektvaru)) {
    inventar.push(lektvar);
}
console.log(`Zlato: ${zlato}`);
console.log(inventar);

Program vypíše:

Otevírám truhlu: Skřetí jeskyně
Otevírám truhlu: Věž čaroděje
Zlato: 170
["Luk", "Léčivý lektvar", "Elixír"]

TypeScript ví, že první volání vrátí číslo, které jde přičíst k proměnné zlato, a druhé pole string[], jehož prvky se vejdou do pole inventar.

Začněte programovat zdarma

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

Nebo se registrujte pomocí:

5/9