Eesti

Avastage TypeScripti geneeriliste tüüpide täiustatud kasutusvõimalusi: piiranguid, abitüüpe, tuletamist ja praktilisi rakendusi robustse ja korduvkasutatava koodi kirjutamiseks globaalses kontekstis.

TypeScripti geneerilised tüübid: täiustatud kasutusmustrid

TypeScripti geneerilised tüübid (generics) on võimas funktsioon, mis võimaldab teil kirjutada paindlikumat, korduvkasutatavamat ja tüübiohutumat koodi. Need võimaldavad teil määratleda tüüpe, mis võivad töötada erinevate teiste tüüpidega, säilitades samal ajal tüübikontrolli kompileerimise ajal. See blogipostitus süveneb täiustatud kasutusmustritesse, pakkudes praktilisi näiteid ja teadmisi igal tasemel arendajatele, olenemata nende geograafilisest asukohast või taustast.

Põhitõdede mõistmine: lühikokkuvõte

Enne täiustatud teemadesse sukeldumist kordame kiiresti üle põhitõed. Geneerilised tüübid võimaldavad luua komponente, mis võivad töötada erinevate tüüpidega, mitte ainult ühega. Geneerilise tüübi parameetri deklareerite nurksulgudes (`<>`) pärast funktsiooni või klassi nime. See parameeter toimib kohatäitena tegeliku tüübi jaoks, mis määratakse hiljem, kui funktsiooni või klassi kasutatakse.

Näiteks võib lihtne geneeriline funktsioon välja näha selline:

function identity(arg: T): T {
  return arg;
}

Selles näites on T geneerilise tüübi parameeter. Funktsioon identity võtab argumendi tüübiga T ja tagastab väärtuse tüübiga T. Seejärel saate seda funktsiooni kutsuda erinevate tüüpidega:


let stringResult: string = identity("hello");
let numberResult: number = identity(42);

Täiustatud geneerilised tüübid: enamat kui põhitõed

Nüüd uurime keerukamaid viise geneeriliste tüüpide kasutamiseks.

1. Geneerilise tüübi piirangud

Tüübipiirangud võimaldavad teil piirata tüüpe, mida saab geneerilise tüübi parameetriga kasutada. See on ülioluline, kui peate tagama, et geneerilisel tüübil on teatud omadused või meetodid. Piirangu määramiseks saate kasutada võtmesõna extends.

Vaatleme näidet, kus soovite, et funktsioon pääseks juurde omadusele length:

function loggingIdentity(arg: T): T {
  console.log(arg.length);
  return arg;
}

Selles näites on T piiratud tüüpidega, millel on omadus length tüübiga number. See võimaldab meil ohutult juurde pääseda arg.length-ile. Katse edastada tüüpi, mis seda piirangut ei täida, põhjustab kompileerimisvea.

Globaalne rakendus: See on eriti kasulik andmetöötlust hõlmavates stsenaariumides, näiteks massiivide või stringidega töötamisel, kus sageli on vaja teada pikkust. See muster töötab samamoodi, olenemata sellest, kas olete Tokyos, Londonis või Rio de Janeiros.

2. Geneeriliste tüüpide kasutamine liidestega

Geneerilised tüübid töötavad sujuvalt liidestega, võimaldades teil määratleda paindlikke ja korduvkasutatavaid liidese definitsioone.

interface GenericIdentityFn {
  (arg: T): T;
}

function identity(arg: T): T {
  return arg;
}

let myIdentity: GenericIdentityFn = identity;

Siin on GenericIdentityFn liides, mis kirjeldab funktsiooni, mis võtab geneerilise tüübi T ja tagastab sama tüübi T. See võimaldab teil määratleda erinevate tüübisignatuuridega funktsioone, säilitades samal ajal tüübiohutuse.

Globaalne perspektiiv: See muster võimaldab teil luua korduvkasutatavaid liideseid erinevat tüüpi objektide jaoks. Näiteks saate luua geneerilise liidese andmeedastusobjektidele (DTO), mida kasutatakse erinevates API-des, tagades ühtsed andmestruktuurid kogu teie rakenduses, olenemata piirkonnast, kus see on juurutatud.

3. Geneerilised klassid

Ka klassid võivad olla geneerilised:


class GenericNumber {
  zeroValue: T;
  add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

See klass GenericNumber mahutab väärtust tüübiga T ja määratleb meetodi add, mis opereerib tüübiga T. Te loote klassi instantsi soovitud tüübiga. See võib olla väga abiks andmestruktuuride, nagu pinud või järjekorrad, loomisel.

Globaalne rakendus: Kujutage ette finantsrakendust, mis peab salvestama ja töötlema erinevaid valuutasid (nt USD, EUR, JPY). Saate kasutada geneerilist klassi, et luua klass CurrencyAmount, kus T esindab valuuta tüüpi, võimaldades tüübiohutuid arvutusi ja erinevate valuutasummade salvestamist.

4. Mitu tüübiparameetrit

Geneerilised tüübid võivad kasutada mitut tüübiparameetrit:


function swap(a: T, b: U): [U, T] {
  return [b, a];
}

let result = swap("hello", 42);
// result[0] is number, result[1] is string

Funktsioon swap võtab kaks eri tüüpi argumenti ja tagastab enniku (tuple), kus tüübid on vahetatud.

Globaalne asjakohasus: Rahvusvahelistes ärirakendustes võib teil olla funktsioon, mis võtab kaks seotud, kuid eri tüüpi andmeüksust ja tagastab neist enniku, näiteks kliendi ID (string) ja tellimuse väärtus (number). See muster ei eelista ühtegi konkreetset riiki ja kohandub ideaalselt globaalsete vajadustega.

5. Tüübiparameetrite kasutamine geneerilistes piirangutes

Saate kasutada tüübiparameetrit piirangu sees.


function getProperty(obj: T, key: K) {
  return obj[key];
}

let obj = { a: 1, b: 2, c: 3 };

let value = getProperty(obj, "a"); // value is number

Selles näites tähendab K extends keyof T, et K saab olla ainult tüübi T võti. See tagab tugeva tüübiohutuse objekti omadustele dünaamiliselt juurdepääsemisel.

Globaalne rakendatavus: See on eriti kasulik konfiguratsiooniobjektide või andmestruktuuridega töötamisel, kus omadustele juurdepääsu tuleb arenduse käigus valideerida. Seda tehnikat saab rakendada rakendustes mis tahes riigis.

6. Geneerilised abitüübid

TypeScript pakub mitmeid sisseehitatud abitüüpe, mis kasutavad geneerilisi tüüpe tavaliste tüübimuutuste tegemiseks. Nende hulka kuuluvad:

Näiteks:


interface User {
  id: number;
  name: string;
  email: string;
}

// Partial - kõik omadused valikulised
let optionalUser: Partial = {};

// Pick - ainult id ja name omadused
let userSummary: Pick = { id: 1, name: 'John' };

Globaalne kasutusjuhtum: Need abivahendid on hindamatud API päringu- ja vastusemudelite loomisel. Näiteks globaalses e-kaubanduse rakenduses saab Partial kasutada uuenduspäringu esitamiseks (kus saadetakse ainult mõned toote andmed), samas kui Readonly võib esindada esiosas kuvatavat toodet.

7. Tüübi tuletamine geneeriliste tüüpidega

TypeScript suudab sageli tuletada tüübiparameetrid argumentide põhjal, mille te geneerilisele funktsioonile või klassile edastate. See võib muuta teie koodi puhtamaks ja lihtsamini loetavaks.


function createPair(a: T, b: T): [T, T] {
  return [a, b];
}

let pair = createPair("hello", "world"); // TypeScript tuletab, et T on string

Sel juhul tuletab TypeScript automaatselt, et T on string, kuna mõlemad argumendid on stringid.

Globaalne mõju: Tüübi tuletamine vähendab vajadust selgesõnaliste tüübiannotatsioonide järele, mis võib muuta teie koodi lühemaks ja loetavamaks. See parandab koostööd erinevates arendusmeeskondades, kus võib esineda erinevaid kogemustasemeid.

8. Tingimuslikud tüübid geneeriliste tüüpidega

Tingimuslikud tüübid koos geneeriliste tüüpidega pakuvad võimsat viisi luua tüüpe, mis sõltuvad teiste tüüpide väärtustest.


type Check = T extends string ? string : number;

let result1: Check = "hello"; // string
let result2: Check = 42; // number

Selles näites on Check tulemuseks string, kui T on string-i alamtüüp, vastasel juhul on tulemuseks number.

Globaalne kontekst: Tingimuslikud tüübid on äärmiselt kasulikud tüüpide dünaamiliseks kujundamiseks teatud tingimuste alusel. Kujutage ette süsteemi, mis töötleb andmeid piirkonna alusel. Tingimuslikke tüüpe saab seejärel kasutada andmete teisendamiseks vastavalt piirkonnaspetsiifilistele andmevormingutele või andmetüüpidele. See on ülioluline rakenduste jaoks, millel on globaalsed andmehalduse nõuded.

9. Geneeriliste tüüpide kasutamine kaardistatud tüüpidega

Kaardistatud tüübid (mapped types) võimaldavad teil teisendada tüübi omadusi teise tüübi põhjal. Paindlikkuse saavutamiseks kombineerige neid geneeriliste tüüpidega:


type OptionsFlags = {
  [K in keyof T]: boolean;
};

interface FeatureFlags {
  darkMode: boolean;
  notifications: boolean;
}

// Loob tüübi, kus iga funktsioonilipp on kas lubatud (true) või keelatud (false)
let featureFlags: OptionsFlags = {
  darkMode: true,
  notifications: false,
};

Tüüp OptionsFlags võtab geneerilise tüübi T ja loob uue tüübi, kus T omadused on nüüd kaardistatud tõeväärtusteks (boolean). See on väga võimas konfiguratsioonide või funktsioonilippudega töötamiseks.

Globaalne rakendus: See muster võimaldab luua konfiguratsioonskeeme, mis põhinevad piirkonnaspetsiifilistel seadetel. See lähenemine võimaldab arendajatel määratleda piirkonnaspetsiifilisi konfiguratsioone (nt piirkonnas toetatud keeled). See võimaldab hõlpsasti luua ja hooldada globaalseid rakenduse konfiguratsioonskeeme.

10. Täiustatud tuletamine `infer` võtmesõnaga

Võtmesõna infer võimaldab teil tingimuslikes tüüpides teistest tüüpidest tüüpe eraldada.


type ReturnType any> = T extends (...args: any) => infer R ? R : any;

function myFunction(): string {
  return "hello";
}

let result: ReturnType = "hello"; // result is string

See näide tuletab funktsiooni tagastustüübi, kasutades võtmesõna infer. See on keerukas tehnika täiustatumaks tüübimanipulatsiooniks.

Globaalne tähtsus: See tehnika võib olla eluliselt tähtis suurtes, hajutatud globaalsetes tarkvaraprojektides, et tagada tüübiohutus keerukate funktsioonisignatuuride ja andmestruktuuridega töötamisel. See võimaldab dünaamiliselt genereerida tüüpe teistest tüüpidest, parandades koodi hooldatavust.

Parimad praktikad ja näpunäited

Kokkuvõte: Geneeriliste tüüpide võimsuse omaksvõtmine globaalselt

TypeScripti geneerilised tüübid on robustse ja hooldatava koodi kirjutamise nurgakivi. Nende täiustatud mustrite valdamisega saate oluliselt parandada oma JavaScripti rakenduste tüübiohutust, korduvkasutatavust ja üldist kvaliteeti. Alates lihtsatest tüübipiirangutest kuni keerukate tingimuslike tüüpideni pakuvad geneerilised tüübid teile tööriistu, mida vajate skaleeritava ja hooldatava tarkvara ehitamiseks globaalsele publikule. Pidage meeles, et geneeriliste tüüpide kasutamise põhimõtted jäävad samaks olenemata teie geograafilisest asukohast.

Rakendades selles artiklis käsitletud tehnikaid, saate luua parema struktuuriga, usaldusväärsemat ja kergesti laiendatavat koodi, mis viib lõppkokkuvõttes edukamate tarkvaraprojektideni, olenemata riigist, mandrist või ärist, millega olete seotud. Võtke geneerilised tüübid omaks ja teie kood tänab teid!