Objets TypeScript comme types de dictionnaire comme dans C#

J'ai du code JavaScript qui utilise des objets comme dictionnaires; par exemple, un objet 'person' contiendra des informations personnelles saisies sur 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 Typescript? ou dois-je utiliser un Tableau?

246
demandé sur user75525 2012-11-29 21:41:44

5 réponses

Bien sûr:

var map: { [email: string]: Customer; } = { };
map['foo@gmail.com'] = new Customer(); // OK
map[14] = new Customer(); // Not OK, 14 is not a string
map['bar@hotmail.com'] = 'x'; // Not OK, 'x' is not a customer

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

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

var map: StringToCustomerMap = { };
// Equivalent to first line of above
420
répondu Ryan Cavanaugh 2016-09-14 13:32:59

Vous pouvez utiliser des interfaces templates comme ceci:

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

let dict: Map<number> = {};
dict["one"] = 1;
64
répondu Dimitar Mazhlekov 2015-09-26 14:59:33

En plus d'utiliser un objet map - Comme , Il y a eu un réel Map objet depuis un certain temps, qui est disponible en TypeScript lors de la compilation vers ES6, ou lors de l'utilisation d'un polyfill avec les définitions de type ES6 :

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

Il prend en charge les mêmes fonctionnalités que Object, et plus encore, 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 présente plusieurs avantages par rapport à l'utilisation d'un objet map-Comme, tel que:

  • soutien pour les clés non basées sur des chaînes, par exemple des nombres ou des objets, qui ne sont pris en charge par Object (non, Object ne prend pas en charge les nombres, il les convertit en chaînes)
  • , Moins de place pour les erreurs lorsque vous n'utilisez pas --noImplicitAny, comme Map a toujours un clé type et un valeur type, alors qu'un objet peut pas un index de signature
  • 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 plus élégante pour les tâches courantes, dont la plupart ne sont pas disponibles via de simples Object s sans pirater les fonctions d'assistance (bien que certaines d'entre elles nécessitent un itérateur ES6 complet / polyfill itérable 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());
57
répondu John Weisz 2017-08-10 11:02:00

Lodash a une implémentation de dictionnaire simple et a un bon support TypeScript

Installer 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
répondu phil 2017-10-25 17:20:28

Vous pouvez également utiliser le type D'enregistrement dans typescript:

export interface nameInterface { 
    propName : Record<string, otherComplexInterface> 
}
1
répondu Twen 2018-03-26 15:18:22