Susipažinkite su išplėstiniais TypeScript generics: apribojimais, pagalbiniais tipais, išvedimu ir praktiniais pritaikymais kuriant patikimą ir pernaudojamą kodą globaliame kontekste.
TypeScript Generics: Išplėstiniai Naudojimo Pavyzdžiai
TypeScript generics yra galinga funkcija, leidžianti rašyti lankstesnį, pernaudojamą ir tipų atžvilgiu saugesnį kodą. Ji leidžia apibrėžti tipus, kurie gali veikti su įvairiais kitais tipais, išlaikant tipų tikrinimą kompiliavimo metu. Šiame tinklaraščio įraše gilinamasi į išplėstinius naudojimo pavyzdžius, pateikiant praktinių pavyzdžių ir įžvalgų visų lygių programuotojams, nepriklausomai nuo jų geografinės padėties ar patirties.
Pagrindų Supratimas: Trumpa Apžvalga
Prieš gilinantis į išplėstines temas, greitai apžvelkime pagrindus. Generics leidžia kurti komponentus, kurie gali veikti su įvairiais tipais, o ne su vienu konkrečiu tipu. Bendrojo tipo parametrą deklaruojate laužtiniuose skliaustuose (`<>`) po funkcijos ar klasės pavadinimo. Šis parametras veikia kaip vietos rezervavimo ženklas tikrajam tipui, kuris bus nurodytas vėliau, kai bus naudojama funkcija ar klasė.
Pavyzdžiui, paprasta bendroji funkcija galėtų atrodyti taip:
function identity(arg: T): T {
return arg;
}
Šiame pavyzdyje T
yra bendrojo tipo parametras. Funkcija identity
priima argumentą tipo T
ir grąžina vertę tipo T
. Tada šią funkciją galite iškviesti su skirtingais tipais:
let stringResult: string = identity("hello");
let numberResult: number = identity(42);
Išplėstiniai Generics: Anapus Pamatų
Dabar panagrinėkime sudėtingesnius būdus, kaip išnaudoti generics.
1. Bendrojo Tipo Apribojimai
Tipų apribojimai leidžia jums apriboti tipus, kurie gali būti naudojami su bendrojo tipo parametru. Tai yra labai svarbu, kai reikia užtikrinti, kad bendrasis tipas turėtų tam tikras savybes ar metodus. Galite naudoti extends
raktinį žodį, kad nurodytumėte apribojimą.
Apsvarstykime pavyzdį, kai norite, kad funkcija pasiektų length
savybę:
function loggingIdentity(arg: T): T {
console.log(arg.length);
return arg;
}
Šiame pavyzdyje T
yra apribotas tipais, kurie turi length
savybę, kurios tipas yra number
. Tai leidžia mums saugiai pasiekti arg.length
. Bandant perduoti tipą, kuris neatitinka šio apribojimo, bus gauta kompiliavimo klaida.
Globalus Pritaikymas: Tai ypač naudinga scenarijuose, susijusiuose su duomenų apdorojimu, pavyzdžiui, dirbant su masyvais ar eilutėmis, kur dažnai reikia žinoti ilgį. Šis modelis veikia taip pat, nepriklausomai nuo to, ar esate Tokijuje, Londone, ar Rio de Žaneire.
2. Generics Naudojimas su Sąsajomis
Generics sklandžiai veikia su sąsajomis, leisdami apibrėžti lanksčias ir pernaudojamas sąsajų definicijas.
interface GenericIdentityFn {
(arg: T): T;
}
function identity(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn = identity;
Čia GenericIdentityFn
yra sąsaja, kuri aprašo funkciją, priimančią bendrąjį tipą T
ir grąžinančią tą patį tipą T
. Tai leidžia jums apibrėžti funkcijas su skirtingomis tipų signatūromis, išlaikant tipų saugumą.
Globali Perspektyva: Šis modelis leidžia jums kurti pernaudojamas sąsajas skirtingų rūšių objektams. Pavyzdžiui, galite sukurti bendrąją sąsają duomenų perdavimo objektams (DTO), naudojamiems skirtingose API, užtikrinant nuoseklias duomenų struktūras visoje jūsų programoje, nepriklausomai nuo regiono, kuriame ji diegiama.
3. Bendrosios Klasės
Klasės taip pat gali būti bendrosios:
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; };
Ši klasė GenericNumber
gali laikyti vertę tipo T
ir apibrėžti add
metodą, kuris veikia su tipu T
. Jūs sukuriate klasės egzempliorių su norimu tipu. Tai gali būti labai naudinga kuriant duomenų struktūras, tokias kaip dėklai (stacks) ar eilės (queues).
Globalus Pritaikymas: Įsivaizduokite finansinę programą, kuriai reikia saugoti ir apdoroti įvairias valiutas (pvz., USD, EUR, JPY). Galėtumėte naudoti bendrąją klasę, kad sukurtumėte `CurrencyAmount
4. Keli Tipų Parametrai
Generics gali naudoti kelis tipų parametrus:
function swap(a: T, b: U): [U, T] {
return [b, a];
}
let result = swap("hello", 42);
// result[0] yra skaičius, result[1] yra eilutė
swap
funkcija priima du skirtingų tipų argumentus ir grąžina rinkinį (tuple) su sukeistais tipais.
Globalus Aktualumas: Tarptautinėse verslo programose galite turėti funkciją, kuri priima du susijusius skirtingų tipų duomenis ir grąžina jų rinkinį, pavyzdžiui, kliento ID (eilutė) ir užsakymo vertę (skaičius). Šis modelis nepalaiko jokios konkrečios šalies ir puikiai prisitaiko prie globalių poreikių.
5. Tipų Parametrų Naudojimas Bendruosiuose Apribojimuose
Galite naudoti tipo parametrą apribojime.
function getProperty(obj: T, key: K) {
return obj[key];
}
let obj = { a: 1, b: 2, c: 3 };
let value = getProperty(obj, "a"); // value yra skaičius
Šiame pavyzdyje K extends keyof T
reiškia, kad K
gali būti tik tipo T
raktas. Tai suteikia stiprų tipų saugumą dinamiškai pasiekiant objekto savybes.
Globalus Pritaikomumas: Tai ypač naudinga dirbant su konfigūracijos objektais ar duomenų struktūromis, kur savybių pasiekimas turi būti patikrintas kūrimo metu. Ši technika gali būti taikoma programose bet kurioje šalyje.
6. Bendrieji Pagalbiniai Tipai
TypeScript pateikia keletą integruotų pagalbinių tipų, kurie naudoja generics atlikti įprastas tipų transformacijas. Tai apima:
Partial
: VisasT
savybes padaro neprivalomas.Required
: VisasT
savybes padaro privalomas.Readonly
: VisasT
savybes padaro tik skaitomas.Pick
: Išrenka savybių rinkinį išT
.Omit
: Pašalina savybių rinkinį išT
.
Pavyzdžiui:
interface User {
id: number;
name: string;
email: string;
}
// Partial - visos savybės neprivalomos
let optionalUser: Partial = {};
// Pick - tik id ir name savybės
let userSummary: Pick = { id: 1, name: 'John' };
Globalus Naudojimo Atvejis: Šie pagalbiniai tipai yra neįkainojami kuriant API užklausų ir atsakymų modelius. Pavyzdžiui, globalioje e-komercijos programoje Partial
gali būti naudojamas atnaujinimo užklausai (kur siunčiama tik dalis produkto detalių), o Readonly
gali atstovauti produktą, rodomą vartotojo sąsajoje.
7. Tipų Išvedimas su Generics
TypeScript dažnai gali išvesti tipų parametrus pagal argumentus, kuriuos perduodate bendrajai funkcijai ar klasei. Tai gali padaryti jūsų kodą švaresnį ir lengviau skaitomą.
function createPair(a: T, b: T): [T, T] {
return [a, b];
}
let pair = createPair("hello", "world"); // TypeScript išveda, kad T yra eilutė
Šiuo atveju TypeScript automatiškai išveda, kad T
yra string
, nes abu argumentai yra eilutės.
Globalus Poveikis: Tipų išvedimas sumažina poreikį aiškiai nurodyti tipus, o tai gali padaryti jūsų kodą glaustesnį ir skaitomesnį. Tai pagerina bendradarbiavimą tarp įvairių kūrėjų komandų, kuriose gali būti skirtingų patirties lygių.
8. Sąlyginiai Tipai su Generics
Sąlyginiai tipai, kartu su generics, suteikia galingą būdą kurti tipus, kurie priklauso nuo kitų tipų verčių.
type Check = T extends string ? string : number;
let result1: Check = "hello"; // eilutė
let result2: Check = 42; // skaičius
Šiame pavyzdyje Check
įvertinama kaip string
, jei T
išplečia string
, kitu atveju ji įvertinama kaip number
.
Globalus Kontekstas: Sąlyginiai tipai yra itin naudingi dinamiškai formuojant tipus pagal tam tikras sąlygas. Įsivaizduokite sistemą, kuri apdoroja duomenis pagal regioną. Sąlyginiai tipai gali būti naudojami transformuoti duomenis pagal regionui specifinius duomenų formatus ar tipus. Tai yra labai svarbu programoms su globaliais duomenų valdymo reikalavimais.
9. Generics Naudojimas su Atvaizduotais Tipais
Atvaizduoti tipai leidžia jums transformuoti tipo savybes remiantis kitu tipu. Derinkite juos su generics lankstumui:
type OptionsFlags = {
[K in keyof T]: boolean;
};
interface FeatureFlags {
darkMode: boolean;
notifications: boolean;
}
// Sukuriamas tipas, kuriame kiekviena funkcionalumo vėliavėlė yra įjungta (true) arba išjungta (false)
let featureFlags: OptionsFlags = {
darkMode: true,
notifications: false,
};
OptionsFlags
tipas priima bendrąjį tipą T
ir sukuria naują tipą, kuriame T
savybės dabar yra atvaizduotos į logines (boolean) vertes. Tai labai galinga dirbant su konfigūracijomis ar funkcionalumo vėliavėlėmis (feature flags).
Globalus Pritaikymas: Šis modelis leidžia kurti konfigūracijos schemas, pagrįstas regionui specifiniais nustatymais. Šis požiūris leidžia kūrėjams apibrėžti regionui specifines konfigūracijas (pvz., regione palaikomas kalbas). Tai leidžia lengvai kurti ir prižiūrėti globalias programų konfigūracijos schemas.
10. Išplėstinis Išvedimas su `infer` Raktiniu Žodžiu
infer
raktinis žodis leidžia jums išgauti tipus iš kitų tipų sąlyginiuose tipuose.
type ReturnType any> = T extends (...args: any) => infer R ? R : any;
function myFunction(): string {
return "hello";
}
let result: ReturnType = "hello"; // result yra eilutė
Šis pavyzdys išveda funkcijos grąžinimo tipą naudojant infer
raktinį žodį. Tai yra sudėtinga technika pažangesniam tipų manipuliavimui.
Globali Reikšmė: Ši technika gali būti gyvybiškai svarbi dideliuose, paskirstytuose globaliuose programinės įrangos projektuose, siekiant užtikrinti tipų saugumą dirbant su sudėtingomis funkcijų signatūromis ir duomenų struktūromis. Ji leidžia dinamiškai generuoti tipus iš kitų tipų, gerinant kodo priežiūrą.
Geriausios Praktikos ir Patarimai
- Naudokite prasmingus pavadinimus: Pasirinkite aprašomuosius pavadinimus savo bendrojo tipo parametrams (pvz.,
TValue
,TKey
), kad pagerintumėte skaitomumą. - Dokumentuokite savo generics: Naudokite JSDoc komentarus, kad paaiškintumėte savo bendrųjų tipų ir apribojimų paskirtį. Tai yra kritiškai svarbu komandiniam bendradarbiavimui, ypač su komandomis, paskirstytomis po visą pasaulį.
- Išlaikykite paprastumą: Venkite perteklinio inžinerinio sudėtingumo su generics. Pradėkite nuo paprastų sprendimų ir refaktorizuokite, kai jūsų poreikiai keičiasi. Per didelis sudėtingumas gali trukdyti supratimui kai kuriems komandos nariams.
- Apsvarstykite apimtį: Atidžiai apsvarstykite savo bendrojo tipo parametrų apimtį. Jie turėtų būti kuo siauresni, kad išvengtumėte nenumatytų tipų neatitikimų.
- Išnaudokite esamus pagalbinius tipus: Kai tik įmanoma, naudokite TypeScript integruotus pagalbinius tipus. Jie gali sutaupyti jums laiko ir pastangų.
- Kruopščiai testuokite: Rašykite išsamius vienetų testus, kad užtikrintumėte, jog jūsų bendrasis kodas veikia kaip tikėtasi su įvairiais tipais.
Išvada: Generics Galios Pritaikymas Globaliu Mastu
TypeScript generics yra tvirtas pagrindas rašant patikimą ir prižiūrimą kodą. Įvaldę šiuos išplėstinius pavyzdžius, galite ženkliai pagerinti savo JavaScript programų tipų saugumą, pernaudojamumą ir bendrą kokybę. Nuo paprastų tipų apribojimų iki sudėtingų sąlyginių tipų, generics suteikia įrankius, kurių jums reikia norint kurti mastelį atlaikančią ir prižiūrimą programinę įrangą globaliai auditorijai. Atminkite, kad generics naudojimo principai išlieka nuoseklūs, nepriklausomai nuo jūsų geografinės padėties.
Taikydami šiame straipsnyje aptartas technikas, galite sukurti geriau struktūrizuotą, patikimesnį ir lengvai plečiamą kodą, kas galiausiai veda prie sėkmingesnių programinės įrangos projektų, nepriklausomai nuo šalies, žemyno ar verslo, su kuriuo esate susiję. Priimkite generics, ir jūsų kodas jums padėkos!