Leçons du module (2/2)
Types Utilitaires
TypeScript fournit plusieurs types d'utilité globaux (Utility Types) pour faciliter les transformations de types courantes. Ces types sont génériques et permettent de créer de nouveaux types à partir de types existants de manière déclarative.
Les cinq types d'utilité les plus utilisés sont :
1. Partial<T>
Rend toutes les propriétés d'un type T optionnelles. C'est extrêmement utile pour les fonctions de mise à jour (update/patch) où l'utilisateur pourrait ne fournir qu'un sous-ensemble de champs :
interface User {
id: number;
name: string;
email: string;
}
// Toutes les propriétés de User deviennent optionnelles : { id?: number; name?: string; email?: string; }
type UserUpdate = Partial<User>;2. Readonly<T>
Rend toutes les propriétés d'un type T en lecture seule (readonly). Toute tentative de réassignation d'une propriété provoquera une erreur du compilateur au moment de la compilation :
interface Point {
x: number;
y: number;
}
const p: Readonly<Point> = { x: 10, y: 20 };
// p.x = 5; // Erreur : impossible d'assigner à 'x' car c'est une propriété en lecture seule3. Pick<T, Keys>
Crée un type en sélectionnant uniquement un ensemble spécifique de clés (représentées par une union de chaînes de caractères) à partir du type T :
interface Article {
id: number;
title: string;
content: string;
views: number;
}
// Sélectionne uniquement 'title' et 'views' : { title: string; views: number; }
type ArticlePreview = Pick<Article, 'title' | 'views'>;4. Omit<T, Keys>
Crée un type en supprimant un ensemble spécifique de clés du type T. C'est le double de Pick :
interface Product {
id: number;
name: string;
price: number;
secretVendorCode: string;
}
// Supprime 'secretVendorCode' : { id: number; name: string; price: number; }
type PublicProduct = Omit<Product, 'secretVendorCode'>;5. Record<Keys, Type>
Crée un type d'objet dont les clés sont Keys et dont les valeurs sont de type Type. C'est très utile pour mapper des clés à des valeurs, représenter des dictionnaires ou des tables de hachage (key-value maps) :
type Page = 'home' | 'about' | 'contact';
interface PageInfo {
title: string;
}
// Crée un dictionnaire avec les clés 'home' | 'about' | 'contact' et les valeurs PageInfo
const nav: Record<Page, PageInfo> = {
home: { title: 'Home Page' },
about: { title: 'About Us' },
contact: { title: 'Contact Us' },
};À vous de jouer
Exercice 1 : Mise à jour de profil avec Partial
Complétez la fonction updateProfile qui accepte un profil original (Profile) et un objet de mises à jour (updates) dans lequel tous les champs de Profile sont optionnels. Elle doit renvoyer un nouvel objet Profile qui combine les propriétés originales avec les mises à jour.
Afficher l'indice
Utilisez le type d'utilité Partial<Profile> pour le paramètre updates, et l'opérateur spread pour fusionner les objets : { ...original, ...updates }.
Solution disponible après 3 tentatives
Exercice 2 : Suppression de champs sensibles avec Omit
Étant donné le type UserAccount, définissez un alias de type appelé SafeUser qui omet la propriété sensible passwordHash.
Afficher l'indice
Utilisez type SafeUser = Omit<UserAccount, 'passwordHash'>; pour omettre le champ spécifié.
Solution disponible après 3 tentatives
Exercice 3 : Configuration publique avec Pick et Readonly
Étant donné le type AppConfig, définissez un alias de type appelé PublicConfig qui est une version en lecture seule (Readonly) contenant uniquement les propriétés apiEndpoint et port sélectionnées via Pick.
Afficher l'indice
Utilisez type PublicConfig = Readonly<Pick<AppConfig, 'apiEndpoint' | 'port'>>;
Solution disponible après 3 tentatives
Exercice 4 : Dictionnaire d'utilisateurs avec Record et Readonly
Étant donné une interface User avec les champs id: number et name: string, créez un type ReadOnlyUser qui rend tous les champs de User en lecture seule. Ensuite, créez un type UserRegistry qui représente un dictionnaire dans lequel la clé est une chaîne (ex. l'id textuel) et la valeur est un ReadOnlyUser.
Afficher l'indice
Utilisez Readonly<User> pour définir ReadOnlyUser, et Record<string, ReadOnlyUser> pour le dictionnaire.
Solution disponible après 3 tentatives