Использовать словарь в машинописном тексте? [Дубликат]

Вы не можете. Это следует за соглашением Java Bean. Поэтому у вас должен быть геттер.

240
задан user75525 30 November 2012 в 11:28
поделиться

5 ответов

Конечно:

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

Вы также можете создать интерфейс, если вы не хотите вводить эту аннотацию всего типа каждый раз:

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

var map: StringToCustomerMap = { };
// Equivalent to first line of above
404
ответ дан Benjamin Hodgson 18 August 2018 в 08:45
поделиться
  • 1
    Это полезный способ убедиться, что компилятор ограничивает индексы строк. Интересно. Не похоже, что тип индекса может быть чем-то другим, кроме строк или целых чисел, но это имеет смысл, поскольку он просто сопоставляется с собственными индексами объектов JS. – Ken Smith 29 November 2012 в 20:03
  • 2
    Вы можете это знать, но есть также некоторые потенциальные проблемы с этим подходом, причем большая из них заключается в том, что нет надежного и простого способа повторения всех членов. Этот код, например, показывает, что map содержит два элемента: (& lt; any & gt; Object.prototype) .something = function () {}; class Customer {} var map: {[email: string]: Клиент; знак равно map ['foo@gmail.com '] = новый клиент (); для (var i на карте) {console.log (map [i])} – Ken Smith 30 November 2012 в 19:21
  • 3
    как вы его удаляете? – TDaver 16 April 2013 в 19:07
  • 4
    Еще один интересный подход: интерфейс MapStringTo & lt; T & gt; {[ключ: строка]: T; } И объявить переменную как var map:MapStringTo<Customer> = {}; – orellabac 24 August 2013 в 01:50
  • 5
    Обратите внимание, что ограничение индекса больше не работает. Подробнее. – David Sherret 13 May 2015 в 15:54

Вы можете использовать шаблонные интерфейсы, такие как:

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

let dict: Map<number> = {};
dict["one"] = 1;
65
ответ дан Dimitar Mazhlekov 18 August 2018 в 08:45
поделиться
  • 1
    Обратите внимание, что это сталкивается с типом карты es6. Лучше, чем другой ответ, потому что ограничение индекса игнорируется. – Old Badman Grey 21 June 2016 в 09:15
  • 2
    как проверить, существует ли ключ в словаре? – samneric 15 May 2017 в 19:42
  • 3
    dict.hasOwnProperty ( 'ключ') – Dimitar Mazhlekov 17 May 2017 в 08:07
  • 4
    Я использую словарь вместо Map, чтобы избежать путаницы, и вы можете использовать литерал для обозначения объекта: let dict: Dictionary<number> = { "one": 1, "two": 2 }; – PhiLho 11 July 2017 в 17:44
  • 5
    Это работает для меня. – Amol Bhor 19 July 2017 в 09:35

В дополнение к использованию объекта map- , подобного , в течение некоторого времени был фактический Map объект , который доступен в TypeScript при компиляции на ES6 , или при использовании polyfill с определениями типа ES6 :

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

Он поддерживает те же функции, что и Object, и многое другое, с немного отличающимся синтаксисом:

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

Это само по себе имеет несколько преимуществ перед использованием объекта map- , подобного , например:

  • Поддержка нестроковых ключей, например числа или объекты, ни один из которых не поддерживается Object (нет, Object не поддерживает числа, он преобразует их в строки)
  • Меньше места для ошибок, когда вы не используете --noImplicitAny, как Map всегда имеет тип и тип значение , тогда как объект может не иметь индексной подписи
  • Функциональность добавления / удаления элементов (пары ключ-значение) оптимизирована для задачи в отличие от создания свойств на Object

Кроме того, [Map обеспечивает более мощный и элегантный API для обычных задач, большинство из которых недоступны с помощью простых Object s без взлома вспомогательных функций (хотя для некоторых из них требуется полный итеративный итеративный полигон ES6 для целей ES5 или ниже) :

// 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());
55
ответ дан John Weisz 18 August 2018 в 08:45
поделиться
  • 1
    Это потрясающе! Но, к сожалению, это было неправильно сериализовано с использованием JSON.stringify(), поэтому его можно использовать, например. для socket.io :( – Lion 25 May 2018 в 17:23
  • 2
    @Lion - ну да, Map сериализация довольно забавная. Я, например, выполняю преобразование объектов с ключом-значностью перед сериализацией, а затем обратно (например, объект { key: "John", value: { firstName: "John" } }). – John Weisz 25 May 2018 в 19:30

Lodash имеет простую реализацию словаря и имеет хорошую поддержку TypeScript

Установить Lodash:

npm install lodash @types/lodash --save

Импорт и использование:

import { Dictionary } from "lodash";
let properties : Dictionary<string> = {
    "key": "value"        
}
console.log(properties["key"])
2
ответ дан phil 18 August 2018 в 08:45
поделиться

Вы также можете использовать тип записи в машинописном тексте:

export interface nameInterface { 
    propName : Record<string, otherComplexInterface> 
}
1
ответ дан Twen 18 August 2018 в 08:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: