Apgūstiet TypeScript utilītu tipus: jaudīgi rīki tipu transformācijām, uzlabojot koda atkārtotu izmantošanu un tipu drošību jūsu lietojumprogrammās.
TypeScript Utilītu Tipi: Iebūvēti Tipu Manipulācijas Rīki
TypeScript ir jaudīga valoda, kas pievieno statisko tipēšanu JavaScript. Viena no tās galvenajām iezīmēm ir spēja manipulēt ar tipiem, ļaujot izstrādātājiem veidot robustāku un uzturēšanai ērtāku kodu. TypeScript nodrošina iebūvētu utilītu tipu komplektu, kas vienkāršo bieži sastopamas tipu transformācijas. Šie utilītu tipi ir nenovērtējami rīki, lai uzlabotu tipu drošību, veicinātu koda atkārtotu izmantošanu un optimizētu jūsu izstrādes darbplūsmu. Šajā visaptverošajā ceļvedī tiek aplūkoti svarīgākie TypeScript utilītu tipi, sniedzot praktiskus piemērus un noderīgas atziņas, kas palīdzēs tos apgūt.
Kas ir TypeScript Utilītu Tipi?
Utilītu tipi ir iepriekš definēti tipu operatori, kas pārveido esošos tipus jaunos tipos. Tie ir iebūvēti TypeScript valodā un nodrošina kodolīgu un deklaratīvu veidu, kā veikt bieži sastopamas tipu manipulācijas. Utilītu tipu izmantošana var ievērojami samazināt lieka koda daudzumu un padarīt jūsu tipu definīcijas izteiksmīgākas un vieglāk saprotamas.
Uztveriet tos kā funkcijas, kas darbojas ar tipiem, nevis vērtībām. Tās pieņem tipu kā ievades datus un atgriež modificētu tipu kā izvades datus. Tas ļauj jums veidot sarežģītas tipu attiecības un transformācijas ar minimālu kodu.
Kāpēc izmantot Utilītu Tipus?
Ir vairāki pārliecinoši iemesli, kāpēc iekļaut utilītu tipus savos TypeScript projektos:
- Palielināta Tipu Drošība: Utilītu tipi palīdz ieviest stingrākus tipu ierobežojumus, samazinot izpildlaika kļūdu iespējamību un uzlabojot jūsu koda vispārējo uzticamību.
- Uzlabota Koda Atkārtota Izmantošana: Izmantojot utilītu tipus, varat izveidot ģenēriskus komponentus un funkcijas, kas darbojas ar dažādiem tipiem, veicinot koda atkārtotu izmantošanu un samazinot dublēšanos.
- Samazināts Lieks Kods: Utilītu tipi nodrošina kodolīgu un deklaratīvu veidu, kā veikt bieži sastopamas tipu transformācijas, samazinot lieka koda daudzumu, kas jums jāraksta.
- Uzlabota Lasāmība: Utilītu tipi padara jūsu tipu definīcijas izteiksmīgākas un vieglāk saprotamas, uzlabojot jūsu koda lasāmību un uzturēšanas ērtumu.
Būtiskākie TypeScript Utilītu Tipi
Apskatīsim dažus no visbiežāk izmantotajiem un noderīgākajiem utilītu tipiem TypeScript. Mēs aplūkosim to mērķi, sintaksi un sniegsim praktiskus piemērus, lai ilustrētu to lietojumu.
1. Partial<T>
Utilītu tips Partial<T>
padara visas tipa T
īpašības par neobligātām. Tas ir noderīgi, ja vēlaties izveidot jaunu tipu, kuram ir dažas vai visas esošā tipa īpašības, bet nevēlaties pieprasīt, lai visas no tām būtu norādītas.
Sintakse:
type Partial<T> = { [P in keyof T]?: T[P]; };
Piemērs:
interface User {
id: number;
name: string;
email: string;
}
type OptionalUser = Partial<User>; // Visas īpašības tagad ir neobligātas
const partialUser: OptionalUser = {
name: "Alice", // Norādīta tikai īpašība 'name'
};
Pielietojuma piemērs: Objekta atjaunināšana, izmantojot tikai noteiktas īpašības. Piemēram, iedomājieties lietotāja profila atjaunināšanas formu. Jūs nevēlaties pieprasīt lietotājiem atjaunināt katru lauku uzreiz.
2. Required<T>
Utilītu tips Required<T>
padara visas tipa T
īpašības par obligātām. Tas ir pretstats Partial<T>
. Tas ir noderīgi, ja jums ir tips ar neobligātām īpašībām un vēlaties nodrošināt, ka visas īpašības ir norādītas.
Sintakse:
type Required<T> = { [P in keyof T]-?: T[P]; };
Piemērs:
interface Config {
apiKey?: string;
apiUrl?: string;
}
type CompleteConfig = Required<Config>; // Visas īpašības tagad ir obligātas
const config: CompleteConfig = {
apiKey: "your-api-key",
apiUrl: "https://example.com/api",
};
Pielietojuma piemērs: Nodrošināt, ka visi konfigurācijas iestatījumi ir sniegti pirms lietojumprogrammas palaišanas. Tas var palīdzēt novērst izpildlaika kļūdas, ko izraisa trūkstoši vai nedefinēti iestatījumi.
3. Readonly<T>
Utilītu tips Readonly<T>
padara visas tipa T
īpašības par tikai lasāmām (readonly). Tas novērš nejaušu objekta īpašību modificēšanu pēc tā izveides. Tas veicina nemainīgumu (immutability) un uzlabo jūsu koda paredzamību.
Sintakse:
type Readonly<T> = { readonly [P in keyof T]: T[P]; };
Piemērs:
interface Product {
id: number;
name: string;
price: number;
}
type ImmutableProduct = Readonly<Product>; // Visas īpašības tagad ir tikai lasāmas
const product: ImmutableProduct = {
id: 123,
name: "Example Product",
price: 25.99,
};
// product.price = 29.99; // Kļūda: Nevar piešķirt vērtību 'price', jo tā ir tikai lasāma īpašība.
Pielietojuma piemērs: Nemainīgu datu struktūru izveide, piemēram, konfigurācijas objekti vai datu pārsūtīšanas objekti (DTO), kurus pēc izveides nevajadzētu modificēt. Tas ir īpaši noderīgi funkcionālās programmēšanas paradigmās.
4. Pick<T, K extends keyof T>
Utilītu tips Pick<T, K extends keyof T>
izveido jaunu tipu, atlasot īpašību kopu K
no tipa T
. Tas ir noderīgi, ja jums ir nepieciešama tikai daļa no esošā tipa īpašībām.
Sintakse:
type Pick<T, K extends keyof T> = { [P in K]: T[P]; };
Piemērs:
interface Employee {
id: number;
name: string;
department: string;
salary: number;
}
type EmployeeNameAndDepartment = Pick<Employee, "name" | "department">; // Atlasa tikai 'name' un 'department'
const employeeInfo: EmployeeNameAndDepartment = {
name: "Bob",
department: "Engineering",
};
Pielietojuma piemērs: Specializētu datu pārsūtīšanas objektu (DTO) izveide, kas satur tikai konkrētai darbībai nepieciešamos datus. Tas var uzlabot veiktspēju un samazināt tīklā pārsūtīto datu apjomu. Iedomājieties, ka nosūtat lietotāja datus klientam, bet izslēdzat sensitīvu informāciju, piemēram, algu. Jūs varētu izmantot Pick, lai nosūtītu tikai `id` un `name`.
5. Omit<T, K extends keyof any>
Utilītu tips Omit<T, K extends keyof any>
izveido jaunu tipu, izlaižot īpašību kopu K
no tipa T
. Tas ir pretstats Pick<T, K extends keyof T>
un ir noderīgs, ja vēlaties izslēgt noteiktas īpašības no esoša tipa.
Sintakse:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
Piemērs:
interface Event {
id: number;
title: string;
description: string;
date: Date;
location: string;
}
type EventSummary = Omit<Event, "description" | "location">; // Izlaiž 'description' un 'location'
const eventPreview: EventSummary = {
id: 1,
title: "Conference",
date: new Date(),
};
Pielietojuma piemērs: Vienkāršotu datu modeļu versiju izveide specifiskiem mērķiem, piemēram, pasākuma kopsavilkuma attēlošanai, neiekļaujot pilnu aprakstu un atrašanās vietu. To var izmantot arī, lai noņemtu sensitīvus laukus pirms datu nosūtīšanas klientam.
6. Exclude<T, U>
Utilītu tips Exclude<T, U>
izveido jaunu tipu, izslēdzot no T
visus tipus, kas ir piešķirami U
. Tas ir noderīgi, ja vēlaties noņemt noteiktus tipus no apvienojuma tipa (union type).
Sintakse:
type Exclude<T, U> = T extends U ? never : T;
Piemērs:
type AllowedFileTypes = "image" | "video" | "audio" | "document";
type MediaFileTypes = "image" | "video" | "audio";
type DocumentFileTypes = Exclude<AllowedFileTypes, MediaFileTypes>; // "document"
const fileType: DocumentFileTypes = "document";
Pielietojuma piemērs: Apvienojuma tipa filtrēšana, lai noņemtu specifiskus tipus, kas konkrētā kontekstā nav relevanti. Piemēram, jūs varētu vēlēties izslēgt noteiktus failu tipus no atļauto failu tipu saraksta.
7. Extract<T, U>
Utilītu tips Extract<T, U>
izveido jaunu tipu, atlasot no T
visus tipus, kas ir piešķirami U
. Tas ir pretstats Exclude<T, U>
un ir noderīgs, ja vēlaties atlasīt specifiskus tipus no apvienojuma tipa.
Sintakse:
type Extract<T, U> = T extends U ? T : never;
Piemērs:
type InputTypes = string | number | boolean | null | undefined;
type PrimitiveTypes = string | number | boolean;
type NonNullablePrimitives = Extract<InputTypes, PrimitiveTypes>; // string | number | boolean
const value: NonNullablePrimitives = "hello";
Pielietojuma piemērs: Specifisku tipu atlasīšana no apvienojuma tipa, pamatojoties uz noteiktiem kritērijiem. Piemēram, jūs varētu vēlēties atlasīt visus primitīvos tipus no apvienojuma tipa, kas ietver gan primitīvos, gan objektu tipus.
8. NonNullable<T>
Utilītu tips NonNullable<T>
izveido jaunu tipu, izslēdzot null
un undefined
no tipa T
. Tas ir noderīgi, ja vēlaties nodrošināt, ka tips nevar būt null
vai undefined
.
Sintakse:
type NonNullable<T> = T extends null | undefined ? never : T;
Piemērs:
type MaybeString = string | null | undefined;
type DefinitelyString = NonNullable<MaybeString>; // string
const message: DefinitelyString = "Hello, world!";
Pielietojuma piemērs: Nodrošināt, ka vērtība nav null
vai undefined
pirms operācijas veikšanas ar to. Tas var palīdzēt novērst izpildlaika kļūdas, ko izraisa negaidītas null vai undefined vērtības. Apsveriet scenāriju, kurā jums jāapstrādā lietotāja adrese, un ir ļoti svarīgi, lai adrese nebūtu null pirms jebkādas operācijas.
9. ReturnType<T extends (...args: any) => any>
Utilītu tips ReturnType<T extends (...args: any) => any>
iegūst funkcijas tipa T
atgriešanas tipu. Tas ir noderīgi, ja vēlaties zināt vērtības tipu, ko funkcija atgriež.
Sintakse:
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
Piemērs:
function fetchData(url: string): Promise<{ data: any }> {
return fetch(url).then(response => response.json());
}
type FetchDataReturnType = ReturnType<typeof fetchData>; // Promise<{ data: any }>
async function processData(data: FetchDataReturnType) {
// ...
}
Pielietojuma piemērs: Funkcijas atgrieztās vērtības tipa noteikšana, īpaši strādājot ar asinhronām operācijām vai sarežģītām funkciju signatūrām. Tas ļauj jums nodrošināt, ka pareizi apstrādājat atgriezto vērtību.
10. Parameters<T extends (...args: any) => any>
Utilītu tips Parameters<T extends (...args: any) => any>
iegūst funkcijas tipa T
parametru tipus kā kortēžu (tuple). Tas ir noderīgi, ja vēlaties zināt argumentu tipus, ko funkcija pieņem.
Sintakse:
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
Piemērs:
function createUser(name: string, age: number, email: string): void {
// ...
}
type CreateUserParams = Parameters<typeof createUser>; // [string, number, string]
function logUser(...args: CreateUserParams) {
console.log("Creating user with:", args);
}
Pielietojuma piemērs: Funkcijas pieņemto argumentu tipu noteikšana, kas var būt noderīgi, veidojot ģenēriskas funkcijas vai dekoratorus, kam jādarbojas ar dažādu signatūru funkcijām. Tas palīdz nodrošināt tipu drošību, dinamiski nododot argumentus funkcijai.
11. ConstructorParameters<T extends abstract new (...args: any) => any>
Utilītu tips ConstructorParameters<T extends abstract new (...args: any) => any>
iegūst konstruktora funkcijas tipa T
parametru tipus kā kortēžu. Tas ir noderīgi, ja vēlaties zināt argumentu tipus, ko konstruktors pieņem.
Sintakse:
type ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;
Piemērs:
class Logger {
constructor(public prefix: string, public enabled: boolean) {}
log(message: string) {
if (this.enabled) {
console.log(`${this.prefix}: ${message}`);
}
}
}
type LoggerConstructorParams = ConstructorParameters<typeof Logger>; // [string, boolean]
function createLogger(...args: LoggerConstructorParams) {
return new Logger(...args);
}
Pielietojuma piemērs: Līdzīgi kā Parameters
, bet specifiski konstruktora funkcijām. Tas palīdz, veidojot rūpnīcas (factories) vai atkarību injekcijas (dependency injection) sistēmas, kurās nepieciešams dinamiski instancēt klases ar dažādām konstruktoru signatūrām.
12. InstanceType<T extends abstract new (...args: any) => any>
Utilītu tips InstanceType<T extends abstract new (...args: any) => any>
iegūst konstruktora funkcijas tipa T
instances tipu. Tas ir noderīgi, ja vēlaties zināt objekta tipu, ko konstruktors izveido.
Sintakse:
type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;
Piemērs:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
type GreeterInstance = InstanceType<typeof Greeter>; // Greeter
const myGreeter: GreeterInstance = new Greeter("World");
console.log(myGreeter.greet());
Pielietojuma piemērs: Konstruktora izveidotā objekta tipa noteikšana, kas ir noderīgi, strādājot ar mantošanu vai polimorfismu. Tas nodrošina tipu drošu veidu, kā atsaukties uz klases instanci.
13. Record<K extends keyof any, T>
Utilītu tips Record<K extends keyof any, T>
konstruē objekta tipu, kura īpašību atslēgas ir K
un īpašību vērtības ir T
. Tas ir noderīgi, lai izveidotu vārdnīcai līdzīgus tipus, kur atslēgas ir zināmas iepriekš.
Sintakse:
type Record<K extends keyof any, T> = { [P in K]: T; };
Piemērs:
type CountryCode = "US" | "CA" | "GB" | "DE";
type CurrencyMap = Record<CountryCode, string>; // { US: string; CA: string; GB: string; DE: string; }
const currencies: CurrencyMap = {
US: "USD",
CA: "CAD",
GB: "GBP",
DE: "EUR",
};
Pielietojuma piemērs: Vārdnīcai līdzīgu objektu izveide, kur ir fiksēts atslēgu komplekts un vēlaties nodrošināt, ka visām atslēgām ir noteikta tipa vērtības. To bieži izmanto, strādājot ar konfigurācijas failiem, datu kartējumiem vai uzmeklēšanas tabulām.
Pielāgoti Utilītu Tipi
Lai gan TypeScript iebūvētie utilītu tipi ir jaudīgi, jūs varat arī izveidot savus pielāgotos utilītu tipus, lai risinātu specifiskas vajadzības savos projektos. Tas ļauj jums iekapsulēt sarežģītas tipu transformācijas un atkārtoti tās izmantot visā jūsu koda bāzē.
Piemērs:
// Utilītu tips, lai iegūtu objekta atslēgas, kurām ir noteikts tips
type KeysOfType<T, U> = { [K in keyof T]: T[K] extends U ? K : never }[keyof T];
interface Person {
name: string;
age: number;
address: string;
phoneNumber: number;
}
type StringKeys = KeysOfType<Person, string>; // "name" | "address"
Labākās prakses Utilītu Tipu Izmantošanā
- Izmantojiet aprakstošus nosaukumus: Piešķiriet saviem utilītu tipiem jēgpilnus nosaukumus, kas skaidri norāda to mērķi. Tas uzlabo jūsu koda lasāmību un uzturēšanas ērtumu.
- Dokumentējiet savus utilītu tipus: Pievienojiet komentārus, lai paskaidrotu, ko jūsu utilītu tipi dara un kā tos vajadzētu lietot. Tas palīdz citiem izstrādātājiem saprast jūsu kodu un pareizi to izmantot.
- Saglabājiet vienkāršību: Izvairieties no pārlieku sarežģītu utilītu tipu veidošanas, kurus ir grūti saprast. Sadaliet sarežģītas transformācijas mazākos, vieglāk pārvaldāmos utilītu tipos.
- Testējiet savus utilītu tipus: Rakstiet vienības testus (unit tests), lai nodrošinātu, ka jūsu utilītu tipi darbojas pareizi. Tas palīdz novērst negaidītas kļūdas un nodrošina, ka jūsu tipi darbojas, kā paredzēts.
- Apsveriet veiktspēju: Lai gan utilītu tipiem parasti nav būtiskas ietekmes uz veiktspēju, esiet uzmanīgi ar savu tipu transformāciju sarežģītību, īpaši lielos projektos.
Noslēgums
TypeScript utilītu tipi ir jaudīgi rīki, kas var ievērojami uzlabot jūsu koda tipu drošību, atkārtotu izmantošanu un uzturēšanas ērtumu. Apgūstot šos utilītu tipus, jūs varat rakstīt robustākas un izteiksmīgākas TypeScript lietojumprogrammas. Šajā ceļvedī ir apskatīti svarīgākie TypeScript utilītu tipi, sniedzot praktiskus piemērus un noderīgas atziņas, kas palīdzēs tos iekļaut jūsu projektos.
Atcerieties eksperimentēt ar šiem utilītu tipiem un izpētīt, kā tos var izmantot, lai risinātu specifiskas problēmas savā kodā. Kļūstot arvien pazīstamākiem ar tiem, jūs atklāsiet, ka izmantojat tos arvien biežāk, lai veidotu tīrākas, vieglāk uzturamas un tipu drošākas TypeScript lietojumprogrammas. Neatkarīgi no tā, vai veidojat tīmekļa lietojumprogrammas, servera puses lietojumprogrammas vai jebko citu, utilītu tipi nodrošina vērtīgu rīku kopumu, lai uzlabotu jūsu izstrādes darbplūsmu un koda kvalitāti. Izmantojot šos iebūvētos tipu manipulācijas rīkus, jūs varat atraisīt pilnu TypeScript potenciālu un rakstīt kodu, kas ir gan izteiksmīgs, gan robusts.