TypeScript Objects as Dictionary types as in C# TypeScript Objects as Dictionary types as in C# arrays arrays

TypeScript Objects as Dictionary types as in C#

In newer versions of typescript you can use:

type Customers = Record<string, Customer>

In older versions you can use:

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

You can also make an interface if you don't want to type that whole type annotation out every time:

interface StringToCustomerMap {    [email: string]: Customer;}var map: StringToCustomerMap = { };// Equivalent to first line of above

In addition to using an map-like object, there has been an actual Map object for some time now, which is available in TypeScript when compiling to ES6, or when using a polyfill with the ES6 type-definitions:

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

It supports the same functionality as Object, and more, with a slightly different 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");

This alone has several advantages over using a map-like object, such as:

  • Support for non-string based keys, e.g. numbers or objects, neither of which are supported by Object (no, Object does not support numbers, it converts them to strings)
  • Less room for errors when not using --noImplicitAny, as a Map always has a key type and a value type, whereas an object might not have an index-signature
  • The functionality of adding/removing items (key-value pairs) is optimized for the task, unlike creating properties on an Object

Additionally, a Map object provides a more powerful and elegant API for common tasks, most of which are not available through simple Objects without hacking together helper functions (although some of these require a full ES6 iterator/iterable polyfill for ES5 targets or below):

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

You can use templated interfaces like this:

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