web-dev-qa-db-fra.com

Objets TypeScript comme types de dictionnaire comme en C #

J'ai du code JavaScript qui utilise des objets comme dictionnaires; Par exemple, un objet 'personne' détiendra quelques détails personnels entrés dans l'adresse e-mail.

var people = {<email> : <'some personal data'>};

adding   > "people[<email>] = <data>;" 
getting  > "var data = people[<email>];" 
deleting > "delete people[<email>];"

Est-il possible de décrire cela en dactylographie? ou dois-je utiliser un tableau?

308
Robert Taylor

Sûr:

var map: { [email: string]: Customer; } = { };
map['[email protected]'] = new Customer(); // OK
map[14] = new Customer(); // Not OK, 14 is not a string
map['[email protected]'] = 'x'; // Not OK, 'x' is not a customer

Vous pouvez également créer une interface si vous ne voulez pas taper à chaque fois cette annotation de type:

interface StringToCustomerMap {
    [email: string]: Customer;
}

var map: StringToCustomerMap = { };
// Equivalent to first line of above

Dans les versions plus récentes de TypeScript, vous pouvez utiliser Record<string, Customer>

496
Ryan Cavanaugh

En plus d'utiliser un objet map - comme , il existe depuis un moment un objet Map , disponible dans TypeScript lors de la compilation pour ES6. , ou lors de l'utilisation d'un polyfill avec l'ES6 définitions de type :

let people = new Map<string, Person>();

Il supporte les mêmes fonctionnalités que Object, et plus, avec une syntaxe légèrement différente:

// Adding an item (a key-value pair):
people.set("John", { firstName: "John", lastName: "Doe" });

// Checking for the presence of a key:
people.has("John"); // true

// Retrieving a value by a key:
people.get("John").lastName; // "Doe"

// Deleting an item by a key:
people.delete("John");

Cela seul a plusieurs avantages sur l’utilisation d’un objet map - comme , tels que:

  • Prise en charge des clés non basées sur des chaînes, par exemple des nombres ou des objets, dont aucun n'est supporté par Object (non, Object ne supporte pas les nombres, il les convertit en chaînes)
  • Moins de place pour les erreurs lorsque vous n'utilisez pas --noImplicitAny, car Map a toujours un type de clé et un type de valeur , , alors qu'un objet pourrait ne pas avoir de signature d'index
  • La fonctionnalité d'ajout/suppression d'éléments (paires clé-valeur) est optimisée pour la tâche, contrairement à la création de propriétés sur un Object

De plus, un objet Map fournit une API plus puissante et élégante pour les tâches courantes, dont la plupart ne sont pas disponibles via de simples Objects sans piratage des fonctions d'assistance (bien que certaines d'entre elles nécessitent un intégrateur ES6 iterator/iterable complet pour les cibles ES5 ou inférieures):

// Iterate over Map entries:
people.forEach((person, key) => ...);

// Clear the Map:
people.clear();

// Get Map size:
people.size;

// Extract keys into array (in insertion order):
let keys = Array.from(people.keys());

// Extract values into array (in insertion order):
let values = Array.from(people.values());
107
John Weisz

Vous pouvez utiliser des interfaces basées sur des modèles comme ceci:

interface Map<T> {
    [K: string]: T;
}

let dict: Map<number> = {};
dict["one"] = 1;
74
Dimitar Mazhlekov

Vous pouvez également utiliser le type Record dans TypeScript:

export interface nameInterface { 
    propName : Record<string, otherComplexInterface> 
}
6
Twen

Lodash a une implémentation simple de Dictionary et supporte bien TypeScript

Installez Lodash:

npm install lodash @types/lodash --save

Importation et utilisation:

import { Dictionary } from "lodash";
let properties : Dictionary<string> = {
    "key": "value"        
}
console.log(properties["key"])
5
phil