TL;DR : Les types d'utilitaires TypeScript sont des fonctions prédéfinies qui transforment les types existants, rendant votre code plus propre et plus facile à maintenir. Cet article explique les types d'utilitaires essentiels avec des exemples concrets, notamment comment mettre à jour les profils utilisateur, gérer les configurations et filtrer les données en toute sécurité.
TypeScript est la pierre angulaire du développement Web moderne, permettant aux développeurs d'écrire du code plus sûr et plus maintenable. En introduisant le typage statique dans JavaScript, TypeScript aide à détecter les erreurs au moment de la compilation. Selon l'enquête 2024 sur les développeurs Stack Overflow, TypeScript se classe au 5ème des technologies de script les plus populaires parmi les développeurs.
Les fonctionnalités étonnantes de TypeScript sont la principale raison de son succès. Par exemple, les types utilitaires aident les développeurs à simplifier la manipulation des types et à réduire le code passe-partout. Les types d'utilitaires ont été introduits dans TypeScript 2.1 et des types d'utilitaires supplémentaires ont été ajoutés dans chaque nouvelle version.
Cet article abordera en détail les types d'utilitaires pour vous aider à maîtriser TypeScript.
Les types utilitaires sont des types génériques prédéfinis dans TypeScript qui rendent possible la transformation de types existants en nouveaux types variantes. Ils peuvent être considérés comme des fonctions au niveau du type qui prennent les types existants comme paramètres et renvoient de nouveaux types en fonction de certaines règles de transformation.
Ceci est particulièrement utile lorsque vous travaillez avec des interfaces, où des variantes modifiées de types déjà existants sont souvent nécessaires sans qu'il soit réellement nécessaire de dupliquer les définitions de type.
Le type d'utilitaire Partial prend un type et rend toutes ses propriétés facultatives. Ce type d'utilitaire est particulièrement utile lorsque le type est imbriqué, car il rend les propriétés facultatives de manière récursive.
Par exemple, disons que vous créez une fonction de mise à jour du profil utilisateur. Dans ce cas, si l'utilisateur ne souhaite pas mettre à jour tous les champs, vous pouvez simplement utiliser le type Partiel et mettre à jour uniquement les champs obligatoires. Ceci est très pratique dans les formulaires et les API où tous les champs ne sont pas obligatoires.
Référez-vous à l'exemple de code suivant.
interface User { id: number; name: string; email?: string; } const updateUser = (user: Partial<User>) => { console.log(Updating user: ${user.name} ); }; updateUser({ name: 'Alice' });
Le type d'utilitaire Required construit un type avec toutes les propriétés du type fourni définies sur requis. Ceci est utile pour s'assurer que toutes les propriétés sont disponibles avant d'enregistrer un objet dans la base de données.
Par exemple, si Obligatoire est utilisé pour l'immatriculation d'une voiture, cela garantira que vous ne manquerez aucune propriété nécessaire comme la marque, le modèle et le kilométrage lors de la création ou de l'enregistrement d'un nouveau dossier de voiture. Ceci est très critique en termes d’intégrité des données.
Reportez-vous à l'exemple de code suivant.
interface User { id: number; name: string; email?: string; } const updateUser = (user: Partial<User>) => { console.log(Updating user: ${user.name} ); }; updateUser({ name: 'Alice' });
Le type d'utilitaire Readonly crée un type où toutes les propriétés sont en lecture seule. Ceci est vraiment utile dans la gestion de la configuration pour protéger les paramètres critiques contre les modifications indésirables.
Par exemple, lorsque votre application dépend de points de terminaison d'API spécifiques, ceux-ci ne doivent pas être sujets à changement au cours de son exécution. Les rendre en lecture seule garantit qu'ils resteront constants pendant tout le cycle de vie de l'application.
Référez-vous à l'exemple de code suivant.
interface Car { make: string; model: string; mileage?: number; } const myCar: Required<Car> = { make: 'Ford', model: 'Focus', mileage: 12000, };
Le type utilitaire Pick** construit un type en sélectionnant un ensemble de propriétés à partir d'un type existant. Ceci est utile lorsque vous devez filtrer des informations essentielles, telles que le nom et l'adresse e-mail de l'utilisateur, pour les afficher dans un tableau de bord ou une vue récapitulative. Cela contribue à améliorer la sécurité et la clarté des données.
Référez-vous à l'exemple de code suivant.
interface Config { apiEndpoint: string; } const config: Readonly<Config> = { apiEndpoint: 'https://api.example.com' }; // config.apiEndpoint = 'https://another-url.com'; // Error: Cannot assign to 'apiEndpoint'
Le type utilitaire Omit construit un type en excluant des propriétés spécifiques d'un type existant.
Par exemple, Omettre sera utile si vous souhaitez partager des données utilisateur avec un tiers mais sans informations sensibles, comme une adresse e-mail. Vous pouvez le faire en définissant un nouveau type qui exclurait ces champs. Surtout dans les API, vous souhaiterez peut-être surveiller ce qui se passe dans vos réponses API.
Voir l'exemple de code suivant.
interface User { id: number; name: string; email: string; } type UserSummary = Pick<User, 'name' | 'email'>; const userSummary: UserSummary = { name: 'Alice', email: 'alice@example.com', };
Le type d'utilitaire Record crée un type d'objet avec des clés et des valeurs spécifiées, ce qui est utile lors du traitement de mappages structurés.
Par exemple, dans le contexte des systèmes de gestion des stocks, le type Record peut être utile pour réaliser des mappages explicites entre les articles et les quantités. Avec ce type de structure, les données d'inventaire sont facilement accessibles et modifiables tout en garantissant que tous les fruits attendus sont pris en compte.
interface User { id: number; name: string; email?: string; } const userWithoutEmail: Omit<User, 'email'> = { id: 1, name: 'Bob', };
Le type utilitaire Exclude** construit un type en excluant des types spécifiques d'une union.
Vous pouvez utiliser Exclure lors de la conception de fonctions qui ne doivent accepter que certains types primitifs (par exemple, des nombres ou des booléens mais pas des chaînes). Cela peut éviter les bogues où des types inattendus pourraient provoquer des erreurs lors de l'exécution.
Référez-vous à l'exemple de code suivant.
type Fruit = 'apple' | 'banana' | 'orange'; type Inventory = Record<Fruit, number>; const inventory: Inventory = { apple: 10, banana: 5, orange: 0, };
Le type utilitaire Extract construit un type en extrayant des types spécifiques d'une union.
Dans les scénarios où vous devez traiter uniquement les valeurs numériques d'une collection de type mixte (comme effectuer des calculs), l'utilisation de Extract garantit que seuls les nombres sont transmis. Ceci est utile dans les pipelines de traitement de données où un typage strict peut éviter les erreurs d'exécution.
Référez-vous à l'exemple de code suivant.
interface User { id: number; name: string; email?: string; } const updateUser = (user: Partial<User>) => { console.log(Updating user: ${user.name} ); }; updateUser({ name: 'Alice' });
Le type utilitaire NonNullable construit un type en excluant null et undefined du type donné.
Dans les applications où certaines valeurs doivent être définies à tout moment, comme les noms d'utilisateur ou les identifiants de produits, les rendre NonNullable garantira que ces champs clés ne seront jamais null ou indéfini. Il est utile lors des validations de formulaires et des réponses des API où les valeurs manquantes seraient susceptibles de causer des problèmes.
Référez-vous à l'exemple de code suivant.
interface Car { make: string; model: string; mileage?: number; } const myCar: Required<Car> = { make: 'Ford', model: 'Focus', mileage: 12000, };
L'utilitaire ReturnType extrait le type de retour d'une fonction.
Lorsque vous travaillez avec des fonctions d'ordre supérieur ou des rappels renvoyant des objets complexes, tels que des coordonnées, l'utilisation de ReturnType simplifie la définition des types de retour attendus sans avoir besoin de les indiquer manuellement à chaque fois. Cela peut accélérer le développement en réduisant les bogues liés aux types incompatibles.
interface Config { apiEndpoint: string; } const config: Readonly<Config> = { apiEndpoint: 'https://api.example.com' }; // config.apiEndpoint = 'https://another-url.com'; // Error: Cannot assign to 'apiEndpoint'
L'utilitaire Paramètres extrait les types de paramètres d'une fonction sous forme de tuple.
Cela permet une extraction et une réutilisation faciles des types de paramètres dans les situations où l'on souhaite manipuler ou valider les paramètres de fonction de manière dynamique, comme lors de l'écriture de wrappers autour de fonctions. Il augmente considérablement la réutilisabilité et la maintenabilité du code dans votre base de code en garantissant la cohérence des signatures de fonctions.
Référez-vous à l'exemple de code suivant.
interface User { id: number; name: string; email: string; } type UserSummary = Pick<User, 'name' | 'email'>; const userSummary: UserSummary = { name: 'Alice', email: 'alice@example.com', };
La combinaison de ces types d'utilitaires peut vous permettre d'obtenir des résultats puissants lors du développement d'une application avec TypeScript. Examinons quelques scénarios dans lesquels plusieurs types d'utilitaires fonctionnent ensemble efficacement.
Vous pouvez créer un type qui nécessite certains champs tout en permettant à d'autres d'être facultatifs.
interface User { id: number; name: string; email?: string; } const userWithoutEmail: Omit<User, 'email'> = { id: 1, name: 'Bob', };
Dans cet exemple, UpdateUser nécessite la propriété id tout en autorisant le nom et l'adresse e-mail à être facultatifs. Ce modèle est utile pour mettre à jour les enregistrements où l'identifiant doit toujours être présent.
Vous souhaiterez peut-être définir des réponses API qui peuvent avoir différentes formes en fonction de certaines conditions.
type Fruit = 'apple' | 'banana' | 'orange'; type Inventory = Record<Fruit, number>; const inventory: Inventory = { apple: 10, banana: 5, orange: 0, };
Ici, ApiResponse vous permet de créer des types de réponse flexibles pour un appel API. En utilisant Pick , vous vous assurez que seules les données utilisateur pertinentes sont incluses dans la réponse.
Vous pourriez rencontrer des situations dans lesquelles vous devrez filtrer des types spécifiques d'un syndicat en fonction de certains critères.
Référez-vous à l'exemple de code suivant.
interface User { id: number; name: string; email?: string; } const updateUser = (user: Partial<User>) => { console.log(Updating user: ${user.name} ); }; updateUser({ name: 'Alice' });
Ici, l'utilitaire Exclude est utilisé pour créer un type ( NonLoadingResponses ) qui exclut le chargement de l'union ResponseTypes d'origine, permettant à la Fonction handleResponse pour accepter uniquement le succès ou l'erreur comme entrées valides.
Bien que les types d'utilitaires soient incroyablement puissants, leur utilisation excessive peut conduire à un code complexe et illisible. Il est essentiel de trouver un équilibre entre l’exploitation de ces utilitaires et le maintien de la clarté du code.
Référez-vous à l'exemple de code suivant.
interface Car { make: string; model: string; mileage?: number; } const myCar: Required<Car> = { make: 'Ford', model: 'Focus', mileage: 12000, };
Assurez-vous que l'objectif de chaque cas d'utilisation d'utilitaire est clair. Évitez d'imbriquer trop d'utilitaires ensemble, car cela pourrait confondre la structure prévue de vos types.
Référez-vous à l'exemple de code suivant.
interface Config { apiEndpoint: string; } const config: Readonly<Config> = { apiEndpoint: 'https://api.example.com' }; // config.apiEndpoint = 'https://another-url.com'; // Error: Cannot assign to 'apiEndpoint'
Bien que les impacts sur les performances soient rares au moment de l'exécution puisque les types TypeScript disparaissent après la compilation, les types complexes peuvent ralentir le compilateur TypeScript, affectant la vitesse de développement.
interface User { id: number; name: string; email: string; } type UserSummary = Pick<User, 'name' | 'email'>; const userSummary: UserSummary = { name: 'Alice', email: 'alice@example.com', };
Il ne fait aucun doute que TypeScript est l'un des langages les plus populaires parmi les développeurs Web. Les types d'utilitaires sont l'une des fonctionnalités uniques de TypeScript qui améliorent considérablement l'expérience de développement TypeScript et la qualité du code lorsqu'ils sont utilisés correctement. Cependant, nous ne devons pas les utiliser pour tous les scénarios car il peut y avoir des problèmes de performances et de maintenabilité du code.
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!