Article écrit par Abdourahmane
Typescript est un langage de programmation fortement typé qui ajoute des fonctionnalités de typage statique à Javascript. L’une des fonctionnalités les plus puissantes de Typescript est la possibilité d’utiliser des types utilitaires, qui permettent aux développeurs de créer des types réutilisables pour résoudre des problèmes spécifiques. Les types utilitaires peuvent être utilisés pour manipuler des types existants, créer de nouveaux types à partir de types existants et valider les types d’entrée pour les fonctions.
Dans cet article, nous allons explorer les différents types utilitaires disponibles en Typescript et comment ils peuvent être utilisés pour résoudre des problèmes spécifiques. Nous allons également explorer la création de types utilitaires personnalisés pour répondre à des besoins spécifiques. Enfin, nous présenterons des exemples concrets de cas d’utilisation des types utilitaires en Typescript pour résoudre des problèmes spécifiques.
Que vous soyez un développeur débutant ou expérimenté, cet article vous fournira les connaissances et les compétences nécessaires pour maîtriser les types utilitaires en Typescript et les utiliser efficacement pour résoudre des problèmes spécifiques dans vos projets.
I – Les types utilitaires couramment utilisés :
Les types utilitaires couramment utilisés sont des outils précieux pour manipuler et transformer des types existants. Ils peuvent être utilisés pour rendre les propriétés d’un objet facultatives, rendre les propriétés obligatoires, créer un nouveau type en sélectionnant un sous-ensemble de propriétés, et bien plus encore. Voici une liste de quelques types utilitaires couramment utilisés en Typescript :
1. Partial
Le type utilitaire Partial permet de rendre toutes les propriétés d’un type donné facultatives. Cela signifie que vous pouvez créer un type qui a les mêmes propriétés qu’un autre type, mais qui autorise également des propriétés manquantes.
interface Employee {
firstName: string;
lastName: string;
age: number;
}
type PartialEmployee = Partial<Employee>;
const partialEmployee: PartialEmployee = {
firstName: "Mouloud",
age: 30
};
2. Required
Le type utilitaire Required permet de rendre toutes les propriétés d’un type donné obligatoires. Cela signifie que vous pouvez créer un type qui a les mêmes propriétés qu’un autre type, mais qui nécessite également que toutes les propriétés soient présentes.
interface Employee {
firstName?: string;
lastName?: string;
age?: number;
}
type RequiredEmployee = Required<Employee>;
const requiredEmployee: RequiredEmployee = {
firstName: "Mouloud",
lastName: "Haouili",
age: 30
};
3. Readonly
Le type utilitaire Readonly permet de créer un type où toutes les propriétés sont en lecture seule. Cela signifie que vous pouvez créer un type dont les propriétés ne peuvent pas être modifiées après leur initialisation.
interface Employee {
readonly firstName: string;
readonly lastName: string;
readonly age: number;
}
const person: Employee = {
firstName: "Mouloud",
lastName: "Haouili",
age: 30
};
person.firstName = "Abdou"; // Erreur de compilation car firstName est en lecture seule
4. Record
Le type utilitaire Record permet de créer un type qui représente un objet avec des clés de type string et des valeurs de type donné.
interface EmployeeInfo{
age: number;
salaire: number;
}
type EmployeeName = "Abdou" | "Mouloud" | "Yassine";
const employee : Record<EmployeeName, EmployeeInfo> = {
Abdou: { age: 26, salaire: 10.000 },
Mouloud: { age: 30, salaire: 50.000},
Yassine: { age: 50, salaire: 40.000},
};
5. Pick
Le type utilitaire Pick permet de créer un nouveau type en sélectionnant un sous-ensemble de propriétés à partir d’un type existant.
interface Employee {
firstName: string;
lastName: string;
age: number;
address: string;
}
type EmployeeBasicInfo = Pick<Employee , "firstName" | "lastName" | "age">;
const personBasicInfo: EmployeeBasicInfo= {
firstName: "Mouloud",
lastName: "Haouili",
age: 30
};
En utilisant ces types utilitaires couramment utilisés, vous pouvez facilement manipuler et transformer des types existants pour répondre à des besoins spécifiques en Typescript. Dans la section suivante, nous allons explorer des types utilitaires plus avancés.
II – Types utilitaires avancés :
En plus des types utilitaires couramment utilisés, Typescript dispose également de types utilitaires plus avancés pour résoudre des problèmes spécifiques. Ces types utilitaires comprennent des outils pour transformer les types de manière récursive, créer des types conditionnels et valider les types d’entrée pour les fonctions. Voici quelques-uns de ces types utilitaires :
1. Omit
Le type utilitaire Omit permet de créer un nouveau type en excluant une ou plusieurs propriétés d’un type existant.
interface Employee {
firstName: string;
lastName: string;
age: number;
address: string;
}
type EmployeeWithoutAddress = Omit<Person, "address">;
const personWithoutAddress: PersonWithoutAddress = {
firstName: "Mouloud",
lastName: "Haouili",
age: 30
};
2. Exclude
Le type utilitaire Exclude permet de créer un nouveau type en excluant les types qui correspondent à un type donné.
type Person = "Mouloud" | "Abdou" | "Yassine";
type Adult = "Mouloud" | "Yassine";
type NonAdult = Exclude<Person, Adult>;
const nonAdult: NonAdult = "Abdou"; // "Abdou" est le seul nom restant
3. Extract
Le type utilitaire Extract permet de créer un nouveau type en sélectionnant les types qui correspondent à un type donné.
type Person = "Mouloud" | "Abdou" | "Yassine";
type Adult = "Mouloud" | "Yassine";
type AdultNames = Extract<Person, Adult>;
const adultNames: AdultNames = "Abdou"; // Erreur de compilation on s'attend à avoir Mouloud ou Yassine
4. ReturnType
Le type utilitaire ReturnType permet de récupérer le type de retour d’une fonction
function addNumber(a: number, b: number): number {
return a + b;
}
type AddReturnType = ReturnType<typeof addNumber>;
const result: AddReturnType = "Ouidou"; // Erreur de compilation car le type de retour est un nombre
5. Non nullable
NonNullable permet de créer un nouveau type en excluant null et undefined à partir d’un type donné.
type NullableString = string | null | undefined;
type NonNullableString = NonNullable<NullableString>;
const str1: NullableString = null;
const str2: NonNullableString = 'hello';
const str3: NonNullableString = null; // Error: Type 'null' is not assignable to type 'string'.
III – Combiner plusieurs types utilitaires
Combiner plusieurs types utilitaires ensemble est un moyen pratique d’obtenir un type qui résout un problème spécifique en utilisant différentes fonctionnalités des types utilitaires. Voici un exemple :
interface User {
id: number;
name: string;
email: string;
password: string;
createdAt: Date;
}
type UserWithoutSensitiveInfo = Omit<User, 'email' | 'password' | 'createdAt'>;
type OptionalUserFields = Partial<User>;
type ReadonlyUser = Readonly<User>;
type CleanUser = Readonly<UserWithoutSensitiveInfo> & OptionalUserFields;
Dans cet exemple, nous avons créé trois types utilitaires différents pour manipuler l’interface User :
-
UserWithoutSensitiveInfo utilise le type utilitaire Omit pour supprimer les propriétés email, password et createdAt de User.
-
OptionalUserFields utilise le type utilitaire Partial pour définir toutes les propriétés de User comme facultatives.
-
ReadonlyUser utilise le type utilitaire Readonly pour définir toutes les propriétés de User comme en lecture seule.
Enfin, nous avons combiné ces trois types utilitaires pour créer CleanUser, qui est un type avec toutes les propriétés de User en lecture seule, sauf email, password et createdAt, qui sont facultatives.
Cette approche permet de créer des types très précis et spécifiques pour répondre à des besoins spécifiques. En combinant différents types utilitaires, vous pouvez créer des types personnalisés qui correspondent exactement à vos besoins.
Conclusion
En conclusion, les types utilitaires sont une fonctionnalité puissante de Typescript qui permettent aux développeurs de créer des types plus précis, plus expressifs et plus faciles à maintenir. Les types utilitaires couramment utilisés tels que Partial
, Readonly
, Pick
et Omit
peuvent grandement améliorer la qualité de votre code en évitant les erreurs de typage courantes et en améliorant la lisibilité du code.
En outre, la création de types utilitaires personnalisés permet aux développeurs de résoudre des problèmes spécifiques en combinant différentes fonctionnalités des types utilitaires de base. Cette approche permet de créer des types très précis et spécifiques pour répondre à des besoins spécifiques.
En somme, l’utilisation des types utilitaires est un élément clé pour tirer le meilleur parti de Typescript et garantir la qualité et la maintenabilité de votre code. En apprenant à les utiliser correctement, les développeurs peuvent améliorer la qualité de leur code et accélérer leur processus de développement.