TypeScript - Types Utilitaires

Bonjour là-bas, futurs magiciens du codage ! Aujourd'hui, nous allons entreprendre un voyage passionnant à travers le royaume magique des Types Utilitaires de TypeScript. Ne vous inquiétez pas si vous êtes nouveau dans la programmation ; je serai votre guide amical, et nous explorerons ces concepts ensemble, pas à pas. Alors, sortez vos baguettes virtuelles (claviers), et plongons dedans !

TypeScript - Utility Types

Qu'est-ce que les Types Utilitaires ?

Avant de commencer, comprenons ce qu'est un Type Utilitaire. Imaginez que vous avez une boîte à outils remplie d'outils divers. Chaque outil vous aide à effectuer une tâche spécifique plus efficacement. C'est exactement ce que sont les Types Utilitaires dans TypeScript - ce sont des outils pré-construits qui nous aident à manipuler et à transformer les types facilement.

Maintenant, regardons chacun de ces outils magiques un par un !

Type Partial dans TypeScript

Le type Partial est comme un sortilège qui rend toutes les propriétés d'un objet optionnelles. C'est super utile lorsque vous voulez créer un objet où vous n'avez pas besoin de spécifier toutes les propriétés.

Voyons-le en action :

interface Magicien {
name: string;
age: number;
house: string;
}

function updateMagicien(magicien: Magicien, fieldsToUpdate: Partial<Magicien>) {
return { ...magicien, ...fieldsToUpdate };
}

const harryPotter: Magicien = {
name: "Harry Potter",
age: 11,
house: "Gryffindor"
};

const harryMiseAJour = updateMagicien(harryPotter, { age: 17 });
console.log(harryMiseAJour);
// Output: { name: "Harry Potter", age: 17, house: "Gryffindor" }

Dans cet exemple, Partial<Magicien> nous permet de mettre à jour uniquement l'âge de Harry sans avoir besoin de spécifier toutes les autres propriétés. C'est comme waving une baguette et dire, "Partial Revelio !"

Type Required dans TypeScript

Le type Required est l'opposé de Partial. C'est comme lancer un sortilège qui rend toutes les propriétés d'un objet obligatoires, même si elles étaient originally optionnelles.

interfaceCreatureMagique {
name: string;
power?: string;
age?: number;
}

const dragon: Required<CreatureMagique> = {
name: "Norwegian Ridgeback",
power: "Respiration de feu",
age: 2
};

// Cela provoquerait une erreur :
// const licorne: Required<CreatureMagique> = {
//   name: "Corne d'argent"
// };

Ici, même si power et age étaient optionnels dans l'interface originale, le type Required les rend obligatoires. C'est comme dire, "Accio toutes les propriétés !"

Type Pick dans TypeScript

Le type Pick vous permet de créer un nouveau type en sélectionnant des propriétés spécifiques d'un type existant. C'est comme utiliser un Sortilège d'Appel pour invoquer uniquement les propriétés dont vous avez besoin.

interface Potion {
name: string;
ingredients: string[];
brewingTime: number;
effect: string;
}

type PotionLabel = Pick<Potion, 'name' | 'effect'>;

const potionPolyjuice: PotionLabel = {
name: "Potion Polyjuice",
effect: "Transforme le buveur en une autre personne"
};

Dans cet exemple, nous avons créé un nouveau type PotionLabel qui ne comprend que les propriétés name et effect de l'interface Potion. C'est parfait lorsque vous avez besoin de quelques détails spécifiques !

Type Omit dans TypeScript

Le type Omit est l'opposé de Pick. Il crée un nouveau type en supprimant des propriétés spécifiques d'un type existant. Pensez-y comme utiliser le Sortilège de Disparition sur certaines propriétés !

interface LivreDeSortilèges {
title: string;
author: string;
pages: number;
secretSpell: string;
}

type LivrePublicDeSortilèges = Omit<LivreDeSortilèges, 'secretSpell'>;

const livreDeSortilègesDeDébutant: LivrePublicDeSortilèges = {
title: "Livre standard des sortilèges, niveau 1",
author: "Miranda Goshawk",
pages: 250
};

Ici, nous avons créé un type LivrePublicDeSortilèges qui inclut toutes les propriétés de LivreDeSortilèges sauf secretSpell. C'est comme dire, "Montre-moi tout sauf le secret !"

Type Readonly dans TypeScript

Le type Readonly est comme lancer un sortilège de protection sur vos propriétés. Il rend toutes les propriétés d'un type en lecture seule, empêchant les modifications accidentelles.

interface Baguette {
wood: string;
core: string;
length: number;
}

const baguetteDeHarry: Readonly<Baguette> = {
wood: "Houx",
core: "Plume de phoenix",
length: 11
};

// Cela provoquerait une erreur :
// baguetteDeHarry.length = 12;

Avec Readonly, nous avons assuré que'une fois qu'une baguette est créée, ses propriétés ne peuvent pas être changées. C'est comme mettre un sortilège infrangible sur vos objets !

Type ReturnType dans TypeScript

Le type ReturnType permet d'extraire le type de retour d'une fonction. C'est comme utiliser Legilimency pour jeter un œil dans une fonction et voir ce qu'elle renvoie !

function lancerSort(sortName: string): { name: string, power: number } {
// Logique de lancement de sortilège ici
return { name: sortName, power: Math.random() * 100 };
}

type ResultatSort = ReturnType<typeof lancerSort>;

const lumos: ResultatSort = {
name: "Lumos",
power: 50
};

Dans cet exemple, ResultatSort est inféré comme { name: string, power: number }, qui est le type de retour de lancerSort. C'est incroyablement utile lorsque vous travaillez avec des fonctions complexes !

Type Record dans TypeScript

Le type Record est un sortilège puissant qui crée un type d'objet avec un type de clé spécifique et un type de valeur spécifique. C'est comme invoquer une carte magique où vous définissez ce que doivent être les clés et les valeurs.

type CoupeDesMaisons = Record<string, number>;

const pointsDesMaisons: CoupeDesMaisons = {
"Gryffindor": 472,
"Hufflepuff": 352,
"Ravenclaw": 426,
"Slytherin": 472
};

Ici, CoupeDesMaisons est un type où les clés sont des chaînes (noms de maisons) et les valeurs sont des nombres (points). Cela garantit que notre objet de points des maisons a la structure correcte.

Type NonNullable dans TypeScript

Le type NonNullable est comme lancer un sortilège pour bannir les valeurs null et undefined. Il crée un nouveau type en excluant null et undefined d'un type donné.

type ObjetMagique = string | number | null | undefined;

type ObjetDefinitif = NonNullable<ObjetMagique>;

const objetDefinit: ObjetDefinitif = "Tunique d'invisibilité";
// Cela provoquerait une erreur :
// const objetNull: ObjetDefinitif = null;

Dans cet exemple, ObjetDefinitif est un type qui peut être soit une chaîne soit un nombre, mais pas null ou undefined. C'est parfait lorsque vous voulez vous assurer que vous travaillez avec des valeurs réelles !

Tableau de Bord des Types Utilitaires

Voici un tableau de bord de référence pour tous les Types Utilitaires que nous avons couverts :

Type Utilitaire Description Exemple
Partial Rend toutes les propriétés dans T optionnelles Partial<Magicien>
Required Rend toutes les propriétés dans T obligatoires Required<CreatureMagique>
Pick<T, K> Crée un type avec uniquement les propriétés K de T Pick<Potion, 'name' | 'effect'>
Omit<T, K> Crée un type sans les propriétés K de T Omit<LivreDeSortilèges, 'secretSpell'>
Readonly Rend toutes les propriétés dans T en lecture seule Readonly<Baguette>
ReturnType Extraye le type de retour d'une fonction type T ReturnType<typeof lancerSort>
Record<K, T> Crée un type d'objet avec des clés de type K et des valeurs de type T Record<string, number>
NonNullable Crée un type en excluant null et undefined de T NonNullable<ObjetMagique>

Et voilà, jeunes sorciers ! Vous avez maintenant maîtrisé les sorts de base des Types Utilitaires de TypeScript. Souvenez-vous, comme toute magie, ces types deviennent plus puissants avec la pratique. Alors, continuez à expérimenter, et bientôt vous lancerez ces types aussi facilement que si vous disiez "Wingardium Leviosa" !

Credits: Image by storyset