396 Stimmen

TypeScript-Objekte als Dictionary-Typen wie in C#

Ich habe einige JavaScript-Code, der Objekte als Wörterbücher verwendet; zum Beispiel eine "Person"-Objekt wird eine einige persönliche Details aus der E-Mail-Adresse verschlüsselt halten.

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

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

Ist es möglich, dies in Typescript zu beschreiben? oder muss ich ein Array verwenden?

614voto

Ryan Cavanaugh Punkte 204278

In neueren Versionen von Typescript können Sie das verwenden:

type Customers = Record<string, Customer>

In älteren Versionen können Sie das verwenden:

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

Sie können auch eine Schnittstelle einrichten, wenn Sie nicht jedes Mal die gesamte Typbezeichnung eingeben wollen:

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

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

156voto

John Weisz Punkte 26673

Neben der Verwendung einer Karte- wie Objekt, hat es eine tatsächliche Map Objekt die in TypeScript verfügbar ist, wenn es nach ES6 kompiliert wird oder wenn ein Polyfill mit der ES6 Typendefinitionen :

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

Es unterstützt die gleiche Funktionalität wie Object und mehr, mit einer etwas anderen Syntax:

// 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");

Dies allein hat mehrere Vorteile gegenüber der Verwendung einer Karte. wie Objekt, wie zum Beispiel:

  • Unterstützung für nicht auf Zeichenfolgen basierende Schlüssel, z. B. Zahlen oder Objekte, die beide nicht von Object (nein, Object keine Zahlen unterstützt, werden sie in Strings umgewandelt)
  • Geringerer Spielraum für Fehler bei Nichtverwendung --noImplicitAny , als Map hat immer eine Schlüssel Typ und eine Wert Typ, während ein Objekt könnte keine Indexsignatur haben
  • Die Funktionalität des Hinzufügens/Entfernens von Elementen (Schlüssel-Wert-Paare) ist für diese Aufgabe optimiert, anders als bei der Erstellung von Eigenschaften auf einer Object

Zusätzlich wird eine Map Objekt bietet eine leistungsfähigere und elegantere API für gängige Aufgaben, von denen die meisten nicht durch einfache Object s, ohne Hilfsfunktionen zusammenhacken zu müssen (obwohl einige dieser Funktionen ein vollständiges ES6-Iterator/Iterable-Polyfill für ES5-Ziele oder darunter erfordern):

// 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());

83voto

Dimitar Mazhlekov Punkte 996

Sie können Vorlagen wie diese verwenden:

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

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

12voto

Nick N. Punkte 11730

Sie können verwenden Record für diese:

https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

Beispiel (Eine Zuordnung zwischen AppointmentStatus enum und einigen Metadaten):

  const iconMapping: Record<AppointmentStatus, Icon> = {
    [AppointmentStatus.Failed]: { Name: 'calendar times', Color: 'red' },
    [AppointmentStatus.Canceled]: { Name: 'calendar times outline', Color: 'red' },
    [AppointmentStatus.Confirmed]: { Name: 'calendar check outline', Color: 'green' },
    [AppointmentStatus.Requested]: { Name: 'calendar alternate outline', Color: 'orange' },
    [AppointmentStatus.None]: { Name: 'calendar outline', Color: 'blue' }
  }

Jetzt mit Schnittstelle als Wert:

interface Icon { Name: string Color: string }

Verwendung:

const icon: SemanticIcon = iconMapping[appointment.Status]

11voto

Twen Punkte 292

Sie können auch den Typ Record in typescript verwenden:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X