Un guide complet pour comprendre le type d’enregistrement TypeScript –

TypeScript Record
type simplifie la gestion des structures d’objets avec des types de valeurs cohérents. Ce guide couvre l’essentiel de Record
y compris sa définition, sa syntaxe et ses différences avec d’autres types comme les tuples. Nous apprendrons à définir et à utiliser Record
dans des scénarios pratiques tels que l’application d’un traitement exhaustif des cas et la cartographie des énumérations. De plus, nous explorerons des utilisations avancées en combinant Record
avec des types d’utilitaires comme Partial
, Pick
et Readonly
.
Introduction
Le Record
type est un type utilitaire qui nous permet de créer un type d’objet avec des clés spécifiées et un type de valeur uniforme. Ce type est particulièrement utile pour définir des mappages et garantir que toutes les valeurs d’un objet sont conformes à un seul type.
Définition du type d’enregistrement
La définition officielle du Documentation TypeScript est:
Record<Keys, Type>
Ici:
Keys
représentent l’ensemble de clés de l’enregistrement, qui peut être une union de chaînes littérales ou un type dérivé d’une union.Type
est le type des valeurs associées à ces clés.
Par exemple, Record<string, number>
définit un objet où chaque clé est une chaîne et chaque valeur est un nombre. Ce type garantit que toutes les propriétés de l’objet ont le même type de valeur, mais les clés peuvent varier.
Comparaison entre un enregistrement et un tuple
Les deux Record
et tuples sont utilisés pour gérer des collections de données, mais ils servent des objectifs différents. Même s’ils stockent plusieurs valeurs, leur structure et leur utilisation diffèrent. Un Record a des propriétés nommées avec un type fixe, alors qu’un tuple est une liste ordonnée d’éléments identifiés par leur position. Voici une comparaison simple :
- Enregistrer. Crée un type d’objet dans lequel toutes les valeurs ont le même type, mais les clés peuvent être flexibles. Ceci est utile pour mapper les clés aux valeurs et garantir que toutes les clés adhèrent à un type spécifique.
- Tuple. Définit un tableau avec un nombre fixe d’éléments, où chaque élément peut avoir un type différent. Les tuples sont utilisés lorsque nous avons besoin d’une collection de taille fixe avec des types spécifiques pour chaque position.
Par exemple, considérons ce qui suit.
Voici un Record
type, qui mappe les clés de chaîne aux valeurs numériques :
type AgeMap = Record<string, number>;
Un type tuple représente un tableau avec une chaîne (nom) et un nombre (âge) à une position fixe :
type Person = [string, number];
Utilisation de base du type d’enregistrement
Le Record
type fournit un moyen simple et efficace de mapper les clés aux valeurs. C’est particulièrement utile lorsque nous devons définir des objets avec des paires clé-valeur spécifiques où les clés sont d’un type particulier et les valeurs sont d’un autre type.
Voici quelques façons de base d’utiliser le Record
tapez pour définir et créer des données structurées.
Définir un enregistrement
Pour définir un Record
nous spécifions les types des clés et des valeurs. L’exemple ci-dessous définit un objet où chaque clé est une chaîne et chaque valeur est également une chaîne. Cela pourrait être utilisé pour une carte générique des données utilisateur :
type User = Record<string, string>;
Création d’un Record
Exemple de type
Certains sites Web ont plusieurs sous-domaines. Supposons que chacun de ces sous-domaines nécessite un certain niveau d’accès administrateur et créons un Record
tapez pour stocker différents rôles d’administrateur et leurs niveaux d’accès correspondants. Ici, UserRoles
et UserStatus
sont Record
types où les clés sont des chaînes littérales spécifiques (admin
, blogAdmin
, docsAdmin
, active
, inactive
, suspended
), et les valeurs sont des chaînes qui décrivent chaque rôle et statut.
Dans un premier temps, nous définissons un Record
taper UserRoles
avec des rôles d’administrateur spécifiques comme clés et leurs descriptions comme valeurs. Le UserRoles
type garantit que tout objet de ce type aura des clés admin
, blogAdmin
et docsAdmin
avec des valeurs de chaîne décrivant chaque rôle. Le roles
L’objet adhère à ce type en fournissant des descriptions pour chaque rôle d’administrateur :
type UserRoles = Record<'admin' | 'blogAdmin' | 'docsAdmin', string>;
const roles: UserRoles = {
admin: 'General Administrator with access to all areas.',
blogAdmin: 'Administrator with access to blog content.',
docsAdmin: 'Administrator with access to documentation.'
};
Ensuite, nous définissons un Record
taper UserStatus
avec des statuts spécifiques comme clés et leurs descriptions comme valeurs. Le UserStatus
type garantit que tout objet de ce type aura des clés active
, inactive
et suspended
avec des valeurs de chaîne décrivant chaque statut. Le userStatus
L’objet adhère à ce type en fournissant des descriptions pour chaque statut :
type UserStatus = Record<'active' | 'inactive' | 'suspended', string>;
const userStatus: UserStatus = {
active: 'User is currently active and can use all features.',
inactive: 'User is currently inactive and cannot access their account.',
suspended: 'User account is suspended due to policy violations.'
};
En créant Record
types de cette manière, nous garantissons que les rôles d’administrateur et les statuts d’utilisateur sont bien définis et cohérents dans toute l’application.
Cas d’utilisation pratique du type d’enregistrement
Dans cette section, nous passerons en revue plusieurs cas d’utilisation pratiques de Record
type pour démontrer sa polyvalence et son efficacité dans différents scénarios.
Cas d’utilisation 1 : Application d’une gestion exhaustive des dossiers
En utilisant Record
définir un mappage entre les valeurs de cas et les messages nous permet de traiter explicitement chaque cas possible. Cela garantit que tous les cas sont couverts et que tout cas manquant entraînera des erreurs de compilation.
Dans l’exemple ci-dessous, statusMessages
est un Record
où les clés sont spécifiques Status
valeurs ('pending'
, 'completed'
, 'failed'
), et chaque touche correspond à un message correspondant. Le getStatusMessage
La fonction utilise cet enregistrement pour renvoyer le message approprié en fonction du status
paramètre. Cette approche garantit que tous les statuts sont traités correctement et de manière cohérente.
Exemple:
type Status = 'pending' | 'completed' | 'failed';
interface StatusInfo {
message: string;
severity: 'low' | 'medium' | 'high';
retryable: boolean;
}
const statusMessages: Record<Status, StatusInfo> = {
pending: {
message: 'Your request is pending.',
severity: 'medium',
retryable: true,
},
completed: {
message: 'Your request has been completed.',
severity: 'low',
retryable: false,
},
failed: {
message: 'Your request has failed.',
severity: 'high',
retryable: true,
},
};
function getStatusMessage(status: Status): string {
const info = statusMessages[status];
return `${info.message} Severity: ${info.severity}, Retryable: ${info.retryable}`;
}
console.log(getStatusMessage('completed'));
Cas d’utilisation 2 : application de la vérification de type dans les applications utilisant des génériques
Les génériques dans TypeScript permettent un code flexible et réutilisable. Lorsqu’il est combiné avec Record
les génériques peuvent aider à appliquer la vérification de type et à garantir que les objets sont conformes à des structures spécifiques.
En utilisant des génériques avec Record
nous pouvons créer des fonctions ou des utilitaires qui génèrent des objets avec un ensemble spécifique de clés et un type de valeur cohérent. Cette approche améliore la sécurité des types et la réutilisabilité dans notre base de code.
Dans l’exemple ci-dessous, le createRecord
la fonction prend un tableau de clés et une valeur, et renvoie un Record
où chaque clé correspond à la valeur fournie. Cette fonction utilise des génériques (K
pour les clés et T
pour le type de valeur) pour garantir que le résultat Record
a la bonne structure.
Exemple:
function createRecord<K extends string, T>(keys: K[], value: T): Record<K, T> {
const record: Partial<Record<K, T>> = {};
keys.forEach(key => record[key] = value);
return record as Record<K, T>;
}
interface RoleInfo {
description: string;
permissions: string[];
}
const userRoles = createRecord(['admin', 'editor', 'viewer'], {
description: 'Default role',
permissions: ['read'],
});
console.log(userRoles);
Cas d’utilisation 3 : mappage d’énumérations sur des données
En utilisant Record
mapper les énumérations aux données nous permet de créer une table de recherche où chaque valeur d’énumération est associée à des informations spécifiques. Ceci est particulièrement utile pour des scénarios tels que la configuration de paramètres basés sur des valeurs d’énumération.
Dans cet exemple, colorHex
est un Record
qui cartographie chacun Color
enum valeur à son code couleur hexadécimal correspondant. Cette approche fournit un moyen clair et sûr de gérer les données liées aux couleurs en fonction des valeurs d’énumération.
Exemple:
enum Color {
Red = 'RED',
Green = 'GREEN',
Blue = 'BLUE',
Yellow = 'YELLOW'
}
interface ColorInfo {
hex: string;
rgb: string;
complementary: string;
}
const colorHex: Record<Color, ColorInfo> = {
[Color.Red]: {
hex: '#FF0000',
rgb: 'rgb(255, 0, 0)',
complementary: '#00FFFF',
},
[Color.Green]: {
hex: '#00FF00',
rgb: 'rgb(0, 255, 0)',
complementary: '#FF00FF',
},
[Color.Blue]: {
hex: '#0000FF',
rgb: 'rgb(0, 0, 255)',
complementary: '#FFFF00',
},
[Color.Yellow]: {
hex: '#FFFF00',
rgb: 'rgb(255, 255, 0)',
complementary: '#0000FF',
},
};
console.log(colorHex[Color.Green]);
Cas d’utilisation 4 : création de tables de recherche
Une table de recherche utilisant Record
aide à mapper les clés (telles que les identifiants, les noms) à des valeurs spécifiques (telles que les descriptions, les codes). Cela peut être utile pour diverses applications, notamment les configurations, les traductions et bien d’autres choses.
Ici, countryCode
est un Record
qui mappe les codes de pays à leurs noms de pays, populations, capitales et continents respectifs. Cette table de recherche permet une récupération rapide et sécurisée des noms de pays et des populations en fonction des codes de pays.
Exemple:
type CountryCode = "US" | "CA" | "MX" | "JP";
interface CountryInfo {
name: string;
population: number;
capital: string;
continent: string;
}
const countryLookup: Record<CountryCode, CountryInfo> = {
US: {
name: "United States",
population: 331000000,
capital: "Washington D.C.",
continent: "North America",
},
CA: {
name: "Canada",
population: 37700000,
capital: "Ottawa",
continent: "North America",
},
MX: {
name: "Mexico",
population: 128000000,
capital: "Mexico City",
continent: "North America",
},
JP: {
name: "Japan",
population: 126300000,
capital: "Tokyo",
continent: "Asia",
},
};
console.log(countryLookup.US);
console.log(countryLookup.US.population);
Itération Record
Espèces
Itération Record
Les types sont importants pour accéder et manipuler les données dans les structures de données. Créons un exemple de données et montrons diverses méthodes sur la façon dont nous pouvons parcourir le TypeScript Record
genres.
Exemples de données :
interface Course {
professor: string;
credits: number;
students: string[];
}
interface Courses {
[key: string]: Course;
}
const courses: Courses = {
Math101: {
professor: "Dr. Eze",
credits: 3,
students: ["Emmanuel", "Bob", "Charlie"],
},
History201: {
professor: "Dr. Jones",
credits: 4,
students: ["Dave", "Eve"],
},
};
En utilisant forEach
. Pour utiliser forEach
avec un Record
convertissez-le en un tableau de paires clé-valeur :
Object.entries(courses).forEach(([key, value]) => {
console.log(`${key}: ${value.professor}, ${value.credits}`);
value.students.forEach(student => {
console.log(`Student: ${student}`);
});
});
En utilisant for...in
. Le for...in
la boucle parcourt les clés d’un Record
:
for (const key in courses) {
if (courses.hasOwnProperty(key)) {
const course = courses[key];
console.log(`${key}: ${course.professor}, ${course.credits}`);
course.students.forEach(student => {
console.log(`Student: ${student}`);
});
}
}
En utilisant Object.keys()
. Object.keys()
renvoie un tableau de Record
Les clés de :
Object.keys(courses).forEach((key) => {
const course = courses[key];
console.log(`${key}: ${course.professor}, ${course.credits}`);
course.students.forEach(student => {
console.log(`Student: ${student}`);
});
});
En utilisant Object.values()
. Object.values()
renvoie un tableau de Record
Les valeurs de :
Object.values(courses).forEach((course) => {
console.log(`${course.professor}, ${course.credits}`);
course.students.forEach(student => {
console.log(`Student: ${student}`);
});
});
Types d’utilisation et d’utilitaires avancés avec Record
Le Record
Le type peut être combiné avec d’autres types d’utilitaires pour obtenir une plus grande flexibilité et une plus grande sécurité de type. Cette section expose des modèles d’utilisation avancés, démontrant comment Record
peut fonctionner avec des types d’utilitaires comme Pick
, Readonly
et Partial
.
Combinaison Record
avec Pick
pour le mappage de type sélectif
Le Pick
Le type d’utilitaire nous permet de créer un nouveau type en sélectionnant des propriétés spécifiques à partir d’un type existant. Ceci est utile lorsque nous souhaitons travailler uniquement avec un sous-ensemble de propriétés d’un type plus grand.
Ici, nous avons créé un nouveau type SelectedProductInfo
en choisissant uniquement le name
et price
propriétés de la ProductInfo
interface, puis en utilisant Record
pour mapper différents produits à ce nouveau type :
interface ProductInfo {
name: string;
price: number;
category: string;
}
type SelectedProductInfo = Pick<ProductInfo, "name" | "price">;
type Product = 'Laptop' | 'Smartphone' | 'Tablet';
const products: Record<Product, SelectedProductInfo> = {
"Laptop": { name: "Dell XPS 15", price: 1500 },
"Smartphone": { name: "iPhone 12", price: 999 },
"Tablet": { name: "iPad Pro", price: 799 }
};
Combinaison Record
avec Readonly
pour les propriétés immuables
Le Readonly
Le type d’utilitaire garantit que les propriétés ne peuvent pas être modifiées une fois qu’elles sont définies. Ceci est utile pour créer des structures de données immuables.
Le ReadonlyProductInfo
tapez dans l’exemple ci-dessous rend toutes les propriétés de ProductInfo
immuable, garantissant que les détails de chaque produit ne peuvent pas être modifiés une fois définis :
type ReadonlyProductInfo = Readonly<ProductInfo>;
const readonlyProducts: Record<Product, ReadonlyProductInfo> = {
"Laptop": { name: "Dell XPS 15", price: 1500, category: "Electronics" },
"Smartphone": { name: "iPhone 12", price: 999, category: "Electronics" },
"Tablet": { name: "iPad Pro", price: 799, category: "Electronics" }
};
Combinaison Record
avec Partial
pour les propriétés facultatives
Le Partial
Le type d’utilitaire rend toutes les propriétés d’un type facultatives. Ceci est utile dans les scénarios dans lesquels toutes les propriétés ne sont pas connues ou requises en même temps.
Ici, le PartialProductInfo
type nous permet de créer des produits avec certaines ou aucune des propriétés définies dans ProductInfo
offrant une flexibilité dans la manière dont les informations sur le produit sont spécifiées :
type PartialProductInfo = Partial<ProductInfo>;
const partialProducts: Record<Product, PartialProductInfo> = {
"Laptop": { name: "Dell XPS 15" },
"Smartphone": { price: 999 },
"Tablet": {}
};
Combinaison Record
avec Record
pour le mappage imbriqué
Une autre utilisation avancée consiste à combiner Record
types pour créer des mappages imbriqués, ce qui peut être particulièrement utile pour gérer des structures de données complexes.
Dans cet exemple, storeInventory
utilise imbriqué Record
types pour mapper les départements à leurs produits et détails respectifs, démontrant comment Record
peuvent être combinés pour une gestion de données plus complexe :
type Department = 'Electronics' | 'Furniture';
type ProductDetails = Record<Product, ProductInfo>;
const storeInventory: Record<Department, ProductDetails> = {
"Electronics": {
"Laptop": { name: "Dell XPS 15", price: 1500, category: "Electronics" },
"Smartphone": { name: "iPhone 12", price: 999, category: "Electronics" },
"Tablet": { name: "iPad Pro", price: 799, category: "Electronics" }
},
"Furniture": {
"Chair": { name: "Office Chair", price: 200, category: "Furniture" },
"Table": { name: "Dining Table", price: 500, category: "Furniture" },
"Sofa": { name: "Living Room Sofa", price: 800, category: "Furniture" }
}
};
Conclusion
Le Record
type est un outil polyvalent pour gérer et structurer les types d’objets car il nous permet de définir des mappages clairs entre les clés et les valeurs, garantissant ainsi la sécurité des types et la cohérence dans notre code.
Pour des informations plus détaillées, reportez-vous au Documentation TypeScript et consultez d’autres ressources supplémentaires telles que TypeScript total et Tutoriel TypeScript pour approfondir votre compréhension de TypeScript Record
système de type.
Source link