Izpētiet TypeScript paplašinātās funkcijas, piemēram, veidņu literāļu tipus un nosacījumu tipus, lai rakstītu izteiksmīgāku un uzturamāku kodu. Apgūstiet tipu manipulācijas sarežģītiem scenārijiem.
TypeScript paplašinātie tipi: Veidņu literāļu un nosacījumu tipu meistarīga pārvaldīšana
TypeScript spēks slēpjas tā jaudīgajā tipu sistēmā. Lai gan pamata tipi, piemēram, string, number un boolean, ir pietiekami daudzos scenārijos, paplašinātas funkcijas, piemēram, veidņu literāļu tipi un nosacījumu tipi, paver jaunu izteiksmības un tipu drošības līmeni. Šajā rokasgrāmatā sniegts visaptverošs pārskats par šiem paplašinātajiem tipiem, izpētot to iespējas un demonstrējot praktiskus pielietojumus.
Izpratne par veidņu literāļu tipiem
Veidņu literāļu tipi balstās uz JavaScript veidņu literāļiem, ļaujot definēt tipus, pamatojoties uz virkņu interpolāciju. Tas ļauj izveidot tipus, kas attēlo konkrētus virkņu modeļus, padarot jūsu kodu robustāku un paredzamāku.
Pamata sintakse un lietojums
Veidņu literāļu tipi izmanto atpakaļvērstās pēdiņas (`), lai iekļautu tipa definīciju, līdzīgi kā JavaScript veidņu literāļi. Atpakaļvērsto pēdiņu iekšienē varat interpolēt citus tipus, izmantojot ${} sintaksi. Šeit notiek maģija – jūs būtībā izveidojat tipu, kas ir virkne, kas tiek konstruēta kompilēšanas laikā, pamatojoties uz tipiem interpolācijas iekšienē.
type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";
type APIEndpoint = `/api/${string}`;
// Lietošanas piemērs
const getEndpoint: APIEndpoint = "/api/users"; // Derīgs
const postEndpoint: APIEndpoint = "/api/products/123"; // Derīgs
const invalidEndpoint: APIEndpoint = "/admin/settings"; // TypeScript šeit nerādīs kļūdu, jo `string` var būt jebkas
Šajā piemērā APIEndpoint ir tips, kas attēlo jebkuru virkni, kas sākas ar /api/. Lai gan šis pamata piemērs ir noderīgs, veidņu literāļu tipu patiesais spēks parādās, tos apvienojot ar specifiskākiem tipu ierobežojumiem.
Apvienošana ar apvienojuma (union) tipiem
Veidņu literāļu tipi patiesi izceļas, ja tos lieto kopā ar apvienojuma (union) tipiem. Tas ļauj jums izveidot tipus, kas attēlo noteiktu virkņu kombināciju kopu.
type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";
type APIPath = "users" | "products" | "orders";
type APIEndpoint = `/${APIPath}/${HTTPMethod}`;
// Derīgi API galapunkti
const getUsers: APIEndpoint = "/users/GET";
const postProducts: APIEndpoint = "/products/POST";
// Nederīgi API galapunkti (rezultēsies TypeScript kļūdās)
// const invalidEndpoint: APIEndpoint = "/users/PATCH"; // Kļūda: "/users/PATCH" nav piešķirams tipam "/users/GET" | "/users/POST" | "/users/PUT" | "/users/DELETE" | "/products/GET" | "/products/POST" | ... vēl 3 ... | "/orders/DELETE".
Tagad APIEndpoint ir ierobežojošāks tips, kas atļauj tikai konkrētas API ceļu un HTTP metožu kombinācijas. TypeScript ziņos par jebkādiem mēģinājumiem izmantot nederīgas kombinācijas, tādējādi uzlabojot tipu drošību.
Virkņu manipulācija ar veidņu literāļu tipiem
TypeScript nodrošina iebūvētus virkņu manipulācijas tipus, kas nevainojami darbojas ar veidņu literāļu tipiem. Šie tipi ļauj pārveidot virknes kompilēšanas laikā.
- Uppercase: Pārveido virkni par lielajiem burtiem.
- Lowercase: Pārveido virkni par mazajiem burtiem.
- Capitalize: Pārveido virknes pirmo burtu par lielo.
- Uncapitalize: Pārveido virknes pirmo lielo burtu par mazo.
type Greeting = "hello world";
type UppercaseGreeting = Uppercase; // "HELLO WORLD"
type LowercaseGreeting = Lowercase; // "hello world"
type CapitalizedGreeting = Capitalize; // "Hello world"
type UncapitalizedGreeting = Uncapitalize; // "hello world"
Šie virkņu manipulācijas tipi ir īpaši noderīgi, lai automātiski ģenerētu tipus, pamatojoties uz nosaukumu piešķiršanas konvencijām. Piemēram, jūs varētu atvasināt darbību tipus no notikumu nosaukumiem vai otrādi.
Praktiski pielietojumi veidņu literāļu tipiem
- API galapunktu definēšana: Kā parādīts iepriekš, definējot API galapunktus ar precīziem tipu ierobežojumiem.
- Notikumu apstrāde: Tipu izveide notikumu nosaukumiem ar specifiskiem prefiksiem un sufiksiem.
- CSS klašu ģenerēšana: CSS klašu nosaukumu ģenerēšana, pamatojoties uz komponentu nosaukumiem un stāvokļiem.
- Datu bāzes vaicājumu veidošana: Tipu drošības nodrošināšana, veidojot datu bāzes vaicājumus.
Starptautisks piemērs: Valūtas formatēšana
Iedomājieties, ka veidojat finanšu lietojumprogrammu, kas atbalsta vairākas valūtas. Jūs varat izmantot veidņu literāļu tipus, lai nodrošinātu pareizu valūtas formatēšanu.
type CurrencyCode = "USD" | "EUR" | "GBP" | "JPY";
type CurrencyFormat = `${number} ${T}`;
const priceUSD: CurrencyFormat<"USD"> = "100 USD"; // Derīgs
const priceEUR: CurrencyFormat<"EUR"> = "50 EUR"; // Derīgs
// const priceInvalid: CurrencyFormat<"USD"> = "100 EUR"; // Kļūda: Tips 'string' nav piešķirams tipam '`${number} USD`'.
function formatCurrency(amount: number, currency: T): CurrencyFormat {
return `${amount} ${currency}`;
}
const formattedUSD = formatCurrency(250, "USD"); // Tips: "250 USD"
const formattedEUR = formatCurrency(100, "EUR"); // Tips: "100 EUR"
Šis piemērs nodrošina, ka valūtas vērtības vienmēr tiek formatētas ar pareizo valūtas kodu, novēršot iespējamās kļūdas.
Iedziļināšanās nosacījumu tipos
Nosacījumu tipi ievieš zarošanās loģiku TypeScript tipu sistēmā, ļaujot definēt tipus, kas ir atkarīgi no citiem tipiem. Šī funkcija ir neticami spēcīga, lai izveidotu ļoti elastīgas un atkārtoti lietojamas tipu definīcijas.
Pamata sintakse un lietojums
Nosacījumu tipi izmanto infer atslēgvārdu un trīskāršo operatoru (nosacījums ? trueTips : falseTips), lai definētu tipu nosacījumus.
type IsString = T extends string ? true : false;
type StringCheck = IsString; // type StringCheck = true
type NumberCheck = IsString; // type NumberCheck = false
Šajā piemērā IsString ir nosacījuma tips, kas pārbauda, vai T ir piešķirams string. Ja tā ir, tips tiek atrisināts kā true; pretējā gadījumā tas tiek atrisināts kā false.
Atslēgvārds infer
Atslēgvārds infer ļauj jums iegūt tipu no cita tipa. Tas ir īpaši noderīgi, strādājot ar sarežģītiem tipiem, piemēram, funkciju tipiem vai masīvu tipiem.
type ReturnType any> = T extends (...args: any) => infer R ? R : any;
function add(a: number, b: number): number {
return a + b;
}
type AddReturnType = ReturnType; // type AddReturnType = number
Šajā piemērā ReturnType iegūst funkcijas tipa T atgriešanās tipu. Nosacījuma tipa daļa infer R secina atgriešanās tipu un piešķir to tipa mainīgajam R. Ja T nav funkcijas tips, tips tiek atrisināts kā any.
Izplatošie nosacījumu tipi
Nosacījumu tipi kļūst izplatoši (distributive), ja pārbaudāmais tips ir "kails" tipa parametrs. Tas nozīmē, ka nosacījuma tips tiek piemērots katram apvienojuma (union) tipa dalībniekam atsevišķi.
type ToArray = T extends any ? T[] : never;
type NumberOrStringArray = ToArray; // type NumberOrStringArray = string[] | number[]
Šajā piemērā ToArray pārveido tipu T par masīva tipu. Tā kā T ir "kails" tipa parametrs (nav ietverts citā tipā), nosacījuma tips tiek piemērots number un string atsevišķi, rezultējoties number[] un string[] apvienojumā.
Praktiski nosacījumu tipu pielietojumi
- Atgriešanās tipu iegūšana: Kā parādīts iepriekš, iegūstot funkcijas atgriešanās tipu.
- Tipu filtrēšana no apvienojuma: Tipa izveide, kas satur tikai konkrētus tipus no apvienojuma.
- Pārslogotu funkciju tipu definēšana: Dažādu funkciju tipu izveide, pamatojoties uz ievades tipiem.
- Tipu aizsargu (type guards) izveide: Funkciju definēšana, kas sašaurina mainīgā tipu.
Starptautisks piemērs: Dažādu datuma formātu apstrāde
Dažādos pasaules reģionos tiek izmantoti atšķirīgi datuma formāti. Jūs varat izmantot nosacījumu tipus, lai apstrādātu šīs variācijas.
type DateFormat = "YYYY-MM-DD" | "MM/DD/YYYY" | "DD.MM.YYYY";
type ParseDate = T extends "YYYY-MM-DD"
? { year: number; month: number; day: number; format: "YYYY-MM-DD" }
: T extends "MM/DD/YYYY"
? { month: number; day: number; year: number; format: "MM/DD/YYYY" }
: T extends "DD.MM.YYYY"
? { day: number; month: number; year: number; format: "DD.MM.YYYY" }
: never;
function parseDate(dateString: string, format: T): ParseDate {
// (Implementācija apstrādātu dažādus datuma formātus)
if (format === "YYYY-MM-DD") {
const [year, month, day] = dateString.split("-").map(Number);
return { year, month, day, format } as ParseDate;
} else if (format === "MM/DD/YYYY") {
const [month, day, year] = dateString.split("/").map(Number);
return { month, day, year, format } as ParseDate;
} else if (format === "DD.MM.YYYY") {
const [day, month, year] = dateString.split(".").map(Number);
return { day, month, year, format } as ParseDate;
} else {
throw new Error("Invalid date format");
}
}
const parsedDateISO = parseDate("2023-10-27", "YYYY-MM-DD"); // Tips: { year: number; month: number; day: number; format: "YYYY-MM-DD"; }
const parsedDateUS = parseDate("10/27/2023", "MM/DD/YYYY"); // Tips: { month: number; day: number; year: number; format: "MM/DD/YYYY"; }
const parsedDateEU = parseDate("27.10.2023", "DD.MM.YYYY"); // Tips: { day: number; month: number; year: number; format: "DD.MM.YYYY"; }
console.log(parsedDateISO.year); // Piekļūstiet gadam, zinot, ka tas tur būs
Šis piemērs izmanto nosacījumu tipus, lai definētu dažādas datuma parsēšanas funkcijas, pamatojoties uz norādīto datuma formātu. Tips ParseDate nodrošina, ka atgrieztajam objektam ir pareizie rekvizīti, pamatojoties uz formātu.
Veidņu literāļu un nosacījumu tipu apvienošana
Īstais spēks parādās, kad jūs apvienojat veidņu literāļu tipus un nosacījumu tipus. Tas ļauj veikt neticami jaudīgas tipu manipulācijas.
type EventName = `on${Capitalize}`;
type ExtractEventPayload = T extends EventName
? { type: T; payload: any } // Vienkāršots demonstrācijai
: never;
type ClickEvent = EventName<"click">; // "onClick"
type MouseOverEvent = EventName<"mouseOver">; // "onMouseOver"
//Piemēra funkcija, kas pieņem tipu
function processEvent(event: T): ExtractEventPayload {
//Reālā implementācijā mēs faktiski nosūtītu notikumu.
console.log(`Processing event ${event}`);
//Reālā implementācijā lietderīgā slodze (payload) būtu atkarīga no notikuma tipa.
return { type: event, payload: {} } as ExtractEventPayload;
}
//Ievērojiet, ka atgriešanas tipi ir ļoti specifiski:
const clickEvent = processEvent("onClick"); // { type: "onClick"; payload: any; }
const mouseOverEvent = processEvent("onMouseOver"); // { type: "onMouseOver"; payload: any; }
//Ja izmantojat citas virknes, jūs saņemat `never`:
// const someOtherEvent = processEvent("someOtherEvent"); // Tips ir `never`
Labākā prakse un apsvērumi
- Saglabājiet vienkāršību: Lai gan šie paplašinātie tipi ir jaudīgi, tie var ātri kļūt sarežģīti. Centieties panākt skaidrību un uzturamību.
- Rūpīgi testējiet: Pārliecinieties, ka jūsu tipu definīcijas darbojas kā paredzēts, rakstot visaptverošus vienības testus.
- Dokumentējiet savu kodu: Skaidri dokumentējiet savu paplašināto tipu mērķi un darbību, lai uzlabotu koda lasāmību.
- Apsveriet veiktspēju: Pārmērīga paplašināto tipu izmantošana var ietekmēt kompilēšanas laiku. Profilējiet savu kodu un optimizējiet, kur nepieciešams.
Noslēgums
Veidņu literāļu tipi un nosacījumu tipi ir jaudīgi rīki TypeScript arsenālā. Apgūstot šos paplašinātos tipus, jūs varat rakstīt izteiksmīgāku, uzturamāku un tipu drošāku kodu. Šīs funkcijas ļauj jums tvert sarežģītas attiecības starp tipiem, ieviest stingrākus ierobežojumus un izveidot ļoti atkārtoti lietojamas tipu definīcijas. Apgūstiet šīs metodes, lai paaugstinātu savas TypeScript prasmes un veidotu robustas un mērogojamas lietojumprogrammas globālai auditorijai.