Istražite TypeScriptove tipove literala predložaka za naprednu manipulaciju nizovima, uspoređivanje uzoraka i validaciju. Naučite s praktičnim primjerima.
Tipovi literala predložaka: Uspoređivanje i provjera valjanosti uzoraka nizova u TypeScriptu
TypeScriptov sustav tipova neprestano se razvija, nudeći programerima moćnije alate za izražavanje složene logike i osiguravanje sigurnosti tipova. Jedna od najzanimljivijih i najsvestranijih značajki uvedenih u novijim verzijama su tipovi literala predložaka. Ovi tipovi omogućuju manipulaciju nizovima na razini tipa, omogućavajući napredno uspoređivanje uzoraka nizova i provjeru valjanosti. To otvara potpuno novi svijet mogućnosti za stvaranje robusnijih i održivijih aplikacija.
Što su tipovi literala predložaka?
Tipovi literala predložaka su oblik tipa koji se konstruira kombiniranjem tipova nizovnih literala i unijskih tipova, slično načinu na koji literali predložaka funkcioniraju u JavaScriptu. Međutim, umjesto stvaranja nizova u vremenu izvođenja, oni stvaraju nove tipove temeljene na postojećim.
Evo osnovnog primjera:
type Greeting<T extends string> = `Hello, ${T}!`;
type MyGreeting = Greeting<"World">; // type MyGreeting = "Hello, World!"
U ovom primjeru, `Greeting` je tip literala predloška koji uzima string tip `T` kao ulaz i vraća novi tip koji je konkatenacija "Hello, ", `T` i "!".
Osnovno uspoređivanje uzoraka nizova
Tipovi literala predložaka mogu se koristiti za osnovno uspoređivanje uzoraka nizova. To vam omogućuje stvaranje tipova koji su valjani samo ako odgovaraju određenom uzorku.
Na primjer, možete stvoriti tip koji prihvaća samo nizove koji počinju s "prefix-":
type PrefixedString<T extends string> = T extends `prefix-${string}` ? T : never;
type ValidPrefixedString = PrefixedString<"prefix-valid">; // type ValidPrefixedString = "prefix-valid"
type InvalidPrefixedString = PrefixedString<"invalid">; // type InvalidPrefixedString = never
U ovom primjeru, `PrefixedString` koristi uvjetni tip za provjeru počinje li ulazni niz `T` s "prefix-". Ako da, tip je sam `T`; inače je `never`. `never` je poseban tip u TypeScriptu koji predstavlja tip vrijednosti koje se nikada ne pojavljuju, učinkovito isključujući nevažeći niz.
Ekstrakcija dijelova niza
Tipovi literala predložaka također se mogu koristiti za izdvajanje dijelova niza. Ovo je posebno korisno kada trebate parsirati podatke iz nizova i pretvoriti ih u različite tipove.
Pretpostavimo da imate niz koji predstavlja koordinatu u formatu "x:10,y:20". Možete koristiti tipove literala predložaka za izdvajanje vrijednosti x i y:
type CoordinateString = `x:${number},y:${number}`;
type ExtractX<T extends CoordinateString> = T extends `x:${infer X},y:${number}` ? X : never;
type ExtractY<T extends CoordinateString> = T extends `x:${number},y:${infer Y}` ? Y : never;
type XValue = ExtractX<"x:10,y:20">; // type XValue = 10
type YValue = ExtractY<"x:10,y:20">; // type YValue = 20
U ovom primjeru, `ExtractX` i `ExtractY` koriste ključnu riječ `infer` za hvatanje dijelova niza koji odgovaraju tipu `number`. `infer` vam omogućuje izdvajanje tipa iz uspoređivanja uzoraka. Izdvojeni tipovi se zatim koriste kao povratni tip uvjetnog tipa.
Napredna provjera valjanosti nizova
Tipovi literala predložaka mogu se kombinirati s drugim TypeScript značajkama, poput unijskih tipova i uvjetnih tipova, za provođenje napredne provjere valjanosti nizova. To vam omogućuje stvaranje tipova koji nameću složena pravila o strukturi i sadržaju nizova.
Na primjer, možete stvoriti tip koji provjerava valjanost ISO 8601 nizova datuma:
type Year = `${number}${number}${number}${number}`;
type Month = `0${number}` | `10` | `11` | `12`;
type Day = `${0}${number}` | `${1 | 2}${number}` | `30` | `31`;
type ISODate = `${Year}-${Month}-${Day}`;
type ValidDate = ISODate extends "2023-10-27" ? true : false; // true
type InvalidDate = ISODate extends "2023-13-27" ? true : false; // false
function processDate(date: ISODate) {
// Function logic here. TypeScript enforces the ISODate format.
return `Processing date: ${date}`;
}
console.log(processDate("2024-01-15")); // Works
//console.log(processDate("2024-1-15")); // TypeScript error: Argument of type '"2024-1-15"' is not assignable to parameter of type '`${number}${number}${number}${number}-${0}${number}-${0}${number}` | `${number}${number}${number}${number}-${0}${number}-${1}${number}` | ... 14 more ... | `${number}${number}${number}${number}-12-31`'.
Ovdje su `Year`, `Month` i `Day` definirani pomoću tipova literala predložaka kako bi predstavljali valjane formate za svaki dio datuma. `ISODate` zatim kombinira ove tipove kako bi stvorio tip koji predstavlja valjani ISO 8601 niz datuma. Primjer također pokazuje kako se ovaj tip može koristiti za provođenje formatiranja podataka u funkciji, sprječavajući prosljeđivanje netočnih formata datuma. To poboljšava pouzdanost koda i sprječava pogreške pri izvođenju uzrokovane nevažećim unosom.
Slučajevi upotrebe u stvarnom svijetu
Tipovi literala predložaka mogu se koristiti u različitim scenarijima u stvarnom svijetu. Evo nekoliko primjera:
- Provjera valjanosti obrasca: Možete koristiti tipove literala predložaka za provjeru formata unosa u obrasce, kao što su adrese e-pošte, telefonski brojevi i poštanski brojevi.
- Provjera valjanosti API zahtjeva: Možete koristiti tipove literala predložaka za provjeru strukture podataka API zahtjeva, osiguravajući da odgovaraju očekivanom formatu. Na primjer, provjera valjanosti koda valute (npr. "USD", "EUR", "GBP").
- Parsiranje konfiguracijske datoteke: Možete koristiti tipove literala predložaka za parsiranje konfiguracijskih datoteka i izdvajanje vrijednosti na temelju specifičnih uzoraka. Razmislite o provjeri valjanosti putanja datoteka u konfiguracijskom objektu.
- Enumi temeljeni na nizovima: Možete stvoriti enume temeljene na nizovima s provjerom valjanosti pomoću tipova literala predložaka.
Primjer: Provjera valjanosti kodova valuta
Pogledajmo detaljniji primjer provjere valjanosti kodova valuta. Želimo osigurati da se u našoj aplikaciji koriste samo valjani ISO 4217 kodovi valuta. Ti kodovi obično su tri velika slova.
type CurrencyCode = `${Uppercase<string>}${Uppercase<string>}${Uppercase<string>}`;
function formatCurrency(amount: number, currency: CurrencyCode) {
// Function logic to format currency based on the provided code.
return `$${amount} ${currency}`;
}
console.log(formatCurrency(100, "USD")); // Works
//console.log(formatCurrency(100, "usd")); // TypeScript error: Argument of type '"usd"' is not assignable to parameter of type '`${Uppercase<string>}${Uppercase<string>}${Uppercase<string>}`'.
//More precise example:
type ValidCurrencyCode = "USD" | "EUR" | "GBP" | "JPY" | "CAD" | "AUD"; // Extend as needed
type StronglyTypedCurrencyCode = ValidCurrencyCode;
function formatCurrencyStronglyTyped(amount: number, currency: StronglyTypedCurrencyCode) {
return `$${amount} ${currency}`;
}
console.log(formatCurrencyStronglyTyped(100, "EUR")); // Works
//console.log(formatCurrencyStronglyTyped(100, "CNY")); // TypeScript error: Argument of type '"CNY"' is not assignable to parameter of type '"USD" | "EUR" | "GBP" | "JPY" | "CAD" | "AUD"'.
Ovaj primjer demonstrira kako stvoriti tip `CurrencyCode` koji prihvaća samo nizove koji se sastoje od tri velika slova. Drugi, strože tipizirani primjer pokazuje kako to dodatno ograničiti na unaprijed definiran popis prihvatljivih valuta.
Primjer: Provjera valjanosti putanja API krajnjih točaka
Drugi slučaj upotrebe je provjera valjanosti putanja API krajnjih točaka. Možete definirati tip koji predstavlja valjanu strukturu API krajnje točke, osiguravajući da se zahtjevi upućuju na ispravne putanje. To je posebno korisno u arhitekturama mikrousluga gdje više usluga može izložiti različite API-je.
type APIServiceName = "users" | "products" | "orders";
type APIEndpointPath = `/${APIServiceName}/${string}`;
function callAPI(path: APIEndpointPath) {
// API call logic
console.log(`Calling API: ${path}`);
}
callAPI("/users/123"); // Valid
callAPI("/products/details"); // Valid
//callAPI("/invalid/path"); // TypeScript error
// Even more specific:
type APIAction = "create" | "read" | "update" | "delete";
type APIEndpointPathSpecific = `/${APIServiceName}/${APIAction}`;
function callAPISpecific(path: APIEndpointPathSpecific) {
// API call logic
console.log(`Calling specific API: ${path}`);
}
callAPISpecific("/users/create"); // Valid
//callAPISpecific("/users/list"); // TypeScript error
To vam omogućuje preciznije definiranje strukture API krajnjih točaka, sprječavajući pogreške u kucanju i osiguravajući dosljednost u cijeloj vašoj aplikaciji. Ovo je osnovni primjer; složeniji uzorci mogu se stvoriti za provjeru valjanosti parametara upita i drugih dijelova URL-a.
Prednosti korištenja tipova literala predložaka
Korištenje tipova literala predložaka za uspoređivanje uzoraka nizova i provjeru valjanosti nudi nekoliko prednosti:
- Poboljšana sigurnost tipova: Tipovi literala predložaka omogućuju vam nametanje strožih ograničenja tipova na nizove, smanjujući rizik od pogrešaka pri izvođenju.
- Poboljšana čitljivost koda: Tipovi literala predložaka čine vaš kod čitljivijim jasnim izražavanjem očekivanog formata nizova.
- Povećana mogućnost održavanja: Tipovi literala predložaka čine vaš kod lakšim za održavanje pružajući jedinstveni izvor istine za pravila provjere valjanosti nizova.
- Bolje developersko iskustvo: Tipovi literala predložaka pružaju bolje automatsko dovršavanje i poruke o pogreškama, poboljšavajući cjelokupno developersko iskustvo.
Ograničenja
Iako su tipovi literala predložaka moćni, imaju i neka ograničenja:
- Složenost: Tipovi literala predložaka mogu postati složeni, posebno kada se radi s zamršenim uzorcima. Ključno je uravnotežiti prednosti sigurnosti tipova s održivošću koda.
- Performanse: Tipovi literala predložaka mogu utjecati na performanse kompilacije, posebno u velikim projektima. To je zato što TypeScript treba provesti složeniju provjeru tipova.
- Ograničena podrška za regularne izraze: Iako tipovi literala predložaka omogućuju uspoređivanje uzoraka, oni ne podržavaju cijeli raspon značajki regularnih izraza. Za visoko složenu provjeru valjanosti nizova, regularni izrazi u vremenu izvođenja i dalje bi mogli biti potrebni uz ove konstrukcije tipova za pravilnu sanitizaciju unosa.
Najbolje prakse
Evo nekoliko najboljih praksi koje treba uzeti u obzir pri korištenju tipova literala predložaka:
- Započnite jednostavno: Započnite s jednostavnim uzorcima i postupno povećavajte složenost prema potrebi.
- Koristite opisna imena: Koristite opisna imena za svoje tipove literala predložaka kako biste poboljšali čitljivost koda.
- Dokumentirajte svoje tipove: Dokumentirajte svoje tipove literala predložaka kako biste objasnili njihovu svrhu i upotrebu.
- Temeljito testirajte: Temeljito testirajte svoje tipove literala predložaka kako biste bili sigurni da se ponašaju kako se očekuje.
- Razmotrite performanse: Budite svjesni utjecaja tipova literala predložaka na performanse kompilacije i optimizirajte svoj kod u skladu s tim.
Zaključak
Tipovi literala predložaka su moćna značajka u TypeScriptu koja vam omogućuje naprednu manipulaciju nizovima, uspoređivanje uzoraka i provjeru valjanosti na razini tipa. Korištenjem tipova literala predložaka možete stvoriti robusnije, održivije i tipski sigurnije aplikacije. Iako imaju neka ograničenja, prednosti korištenja tipova literala predložaka često nadmašuju nedostatke, čineći ih vrijednim alatom u arsenalu svakog TypeScript programera. Kako se TypeScript jezik nastavlja razvijati, razumijevanje i korištenje ovih naprednih značajki tipova bit će ključno za izgradnju visokokvalitetnog softvera. Ne zaboravite uravnotežiti složenost s čitljivošću i uvijek dajte prednost temeljitom testiranju.