TypeScript est devenu le langage incontournable pour créer des applications JavaScript évolutives. Dans ce guide complet, nous explorerons les concepts avancés de TypeScript qui amélioreront vos compétences en développement et vous aideront à écrire du code plus sûr.
Comprendre les relations de types complexes :
type IsArray<T> = T extends any[] ? true : false; type IsString<T> = T extends string ? true : false; // Usage type CheckArray = IsArray<string[]>; // true type CheckString = IsString<"hello">; // true // More complex conditional types type UnwrapPromise<T> = T extends Promise<infer U> ? U : T; type ArrayElement<T> = T extends (infer U)[] ? U : never; // Example usage type PromiseString = UnwrapPromise<Promise<string>>; // string type NumberArray = ArrayElement<number[]>; // number
Exploiter les types littéraux de chaîne pour une meilleure sécurité des types :
type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; type APIEndpoint = '/users' | '/posts' | '/comments'; type APIRoute = `${HTTPMethod} ${APIEndpoint}`; // Valid routes const validRoute: APIRoute = 'GET /users'; const validRoute2: APIRoute = 'POST /posts'; // Error: Type '"PATCH /users"' is not assignable to type 'APIRoute' // const invalidRoute: APIRoute = 'PATCH /users'; // Dynamic template literal types type PropEventType<T extends string> = `on${Capitalize<T>}`; type ButtonEvents = PropEventType<'click' | 'hover' | 'focus'>; // Results in: 'onClick' | 'onHover' | 'onFocus'
Création d'interfaces génériques flexibles mais sécurisées :
interface Database<T extends { id: string }> { find(id: string): Promise<T | null>; create(data: Omit<T, 'id'>): Promise<T>; update(id: string, data: Partial<T>): Promise<T>; delete(id: string): Promise<boolean>; } // Implementation example class MongoDatabase<T extends { id: string }> implements Database<T> { constructor(private collection: string) {} async find(id: string): Promise<T | null> { // Implementation return null; } async create(data: Omit<T, 'id'>): Promise<T> { // Implementation return { id: 'generated', ...data } as T; } async update(id: string, data: Partial<T>): Promise<T> { // Implementation return { id, ...data } as T; } async delete(id: string): Promise<boolean> { // Implementation return true; } }
Transformations de types avancées :
type Getters<T> = { [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K] }; interface Person { name: string; age: number; } type PersonGetters = Getters<Person>; // Results in: // { // getName: () => string; // getAge: () => number; // } // Advanced key remapping with filtering type FilteredKeys<T, U> = { [K in keyof T as T[K] extends U ? K : never]: T[K] }; interface Mixed { name: string; count: number; isActive: boolean; data: object; } type StringKeys = FilteredKeys<Mixed, string>; // Results in: { name: string }
Création de puissants décorateurs basés sur les métadonnées :
function ValidateProperty(validationFn: (value: any) => boolean) { return function (target: any, propertyKey: string) { let value: any; const getter = function() { return value; }; const setter = function(newVal: any) { if (!validationFn(newVal)) { throw new Error(`Invalid value for ${propertyKey}`); } value = newVal; }; Object.defineProperty(target, propertyKey, { get: getter, set: setter, enumerable: true, configurable: true, }); }; } class User { @ValidateProperty((value) => typeof value === 'string' && value.length > 0) name: string; @ValidateProperty((value) => typeof value === 'number' && value >= 0) age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } }
Construire des transformations de type puissantes :
// Deep Partial type type DeepPartial<T> = { [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]; }; // Deep Required type type DeepRequired<T> = { [P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P]; }; // Deep Readonly type type DeepReadonly<T> = { readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P]; }; // Example usage interface Config { server: { port: number; host: string; options: { timeout: number; retries: number; }; }; database: { url: string; name: string; }; } type PartialConfig = DeepPartial<Config>; // Now we can have partial nested objects const config: PartialConfig = { server: { port: 3000 // host and options can be omitted } };
Implémentation du modèle de constructeur avec sécurité de type totale :
class RequestBuilder<T = {}> { private data: T; constructor(data: T = {} as T) { this.data = data; } with<K extends string, V>( key: K, value: V ): RequestBuilder<T & { [key in K]: V }> { return new RequestBuilder({ ...this.data, [key]: value, }); } build(): T { return this.data; } } // Usage const request = new RequestBuilder() .with('url', 'https://api.example.com') .with('method', 'GET') .with('headers', { 'Content-Type': 'application/json' }) .build(); // Type is inferred correctly type Request = typeof request; // { // url: string; // method: string; // headers: { 'Content-Type': string }; // }
Création d'un système de gestion des erreurs robuste :
class Result<T, E extends Error> { private constructor( private value: T | null, private error: E | null ) {} static ok<T>(value: T): Result<T, never> { return new Result(value, null); } static err<E extends Error>(error: E): Result<never, E> { return new Result(null, error); } map<U>(fn: (value: T) => U): Result<U, E> { if (this.value === null) { return new Result(null, this.error); } return new Result(fn(this.value), null); } mapError<F extends Error>(fn: (error: E) => F): Result<T, F> { if (this.error === null) { return new Result(this.value, null); } return new Result(null, fn(this.error)); } unwrap(): T { if (this.value === null) { throw this.error; } return this.value; } } // Usage example function divide(a: number, b: number): Result<number, Error> { if (b === 0) { return Result.err(new Error('Division by zero')); } return Result.ok(a / b); } const result = divide(10, 2) .map(n => n * 2) .unwrap(); // 10
Ces modèles TypeScript avancés démontrent la puissance du langage dans la création d'applications sécurisées et maintenables. En maîtrisant ces concepts, vous serez mieux équipé pour créer des applications robustes qui exploitent au maximum le système de types de TypeScript.
Documentation TypeScript
Exploration approfondie de TypeScript
Référentiel GitHub TypeScript
Partagez vos expériences avec ces modèles dans les commentaires ci-dessous ! Quelles fonctionnalités avancées de TypeScript avez-vous trouvées les plus utiles dans vos projets ?
Balises : #typescript #javascript #webdevelopment #programming #typing
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!