array-uri - Obiecte TypeScript ca tipuri Dictionary ca în C#
Am niște cod JavaScript care folosește obiecte ca dicționare; de exemplu, un obiect 'persoană' va conține câteva detalii personale indexate după adresa de email.
var people = {<email> : <'some personal data'>};
adding > "people[<email>] = <data>;"
getting > "var data = people[<email>];"
deleting > "delete people[<email>];"
Este posibil să descriu asta în Typescript? Sau trebuie să folosesc un Array?
Răspuns #1
În versiunile mai noi de TypeScript poți folosi:
type Customers = Record<string, Customer>
În versiunile mai vechi poți folosi:
var map: { [email: string]: Customer; } = { };
map['[email '] = new Customer(); // OK
map[14] = new Customer(); // Not OK, 14 is not a string
map['[email '] = 'x'; // Not OK, 'x' is not a customer
De asemenea, poți crea o interfață dacă nu vrei să scrii acea întreagă notație de tip de fiecare dată:
interface StringToCustomerMap {
[email: string]: Customer;
}
var map: StringToCustomerMap = { };
// Equivalent to first line of above
Răspunsul #2
Pe lângă utilizarea unui obiect asemănător unei hărți, există de ceva timp un obiect Map real, care este disponibil în TypeScript atunci când se compilează către ES6, sau atunci când se folosește un polyfill cu definițiile de tip ES6:
let people = new Map<string, Person>();
Suportă aceeași funcționalitate ca Object și chiar mai mult, cu o sintaxă ușor diferită:
// 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");
Acesta singur are mai multe avantaje față de utilizarea unui obiect asemănător unui map, cum ar fi:
- Suport pentru chei care nu sunt șiruri de caractere, de exemplu numere sau obiecte, nici unul dintre acestea nefiind suportat de
Object(nu,Objectnu suportă numere, le convertește în șiruri de caractere) - Mai puțin spațiu pentru erori atunci când nu se folosește
--noImplicitAny, deoarece unMapare întotdeauna un tip de cheie și un tip de valoare, în timp ce un obiect ar putea să nu aibă o semnătură de index - Funcționalitatea de adăugare/îndepărtare a elementelor (perechi cheie-valoare) este optimizată pentru sarcină, spre deosebire de crearea de proprietăți pe un
Object
În plus, un obiect Map oferă un API mai puternic și mai elegant pentru sarcinile comune, majoritatea acestora nefiind disponibile prin simplele Object-uri fără a improviza funcții ajutătoare (deși unele dintre acestea necesită un polyfill complet pentru iterator/iterabil ES6 pentru ținte ES5 sau inferioare):
// 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());
Răspunsul #3
Poți folosi interfețe cu șabloane ca acestea:
interface Map<T> {
[K: string]: T;
}
let dict: Map<number> = {};
dict["one"] = 1;
Răspunsul #4
Poți folosi Record pentru aceasta:
https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt
Exemplu (O corespondență între enum-ul AppointmentStatus și unele metadate):
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' }
}
Acum cu interfața ca valoare:
interfață Icon { Name: string Color: string }
Utilizare :
const icon: SemanticIcon = iconMapping[appointment.Status]Răspunsul #5
De asemenea, poți folosi tipul Record în TypeScript:
export interface nameInterface {
propName : Record<string, otherComplexInterface>
}
