ES6 Map in Typescript

JavascriptTypescripttypescript1.5

Javascript Problem Overview


I'm creating a class in typescript that has a property that is an ES6 (ECMAscript 2016) Map like so:

class Item {
  configs: ????;
  constructor () {
    this.configs = new Map();
  }
}

How do I declare an ES6 Map type in typescript?

Javascript Solutions


Solution 1 - Javascript

EDIT (Jun 5 2019): While the idea that "TypeScript supports Map natively" is still true, since version 2.1 TypeScript supports something called Record.

type MyMapLikeType = Record<string, IPerson>;
const peopleA: MyMapLikeType = {
    "a": { name: "joe" },
    "b": { name: "bart" },
};

Unfortunately the first generic parameter (key type) is still not fully respected: even with a string type, something like peopleA[0] (a number) is still valid.


EDIT (Apr 25 2016): The answer below is old and should not be considered the best answer. TypeScript does support Maps "natively" now, so it simply allows ES6 Maps to be used when the output is ES6. For ES5, it does not provide polyfills; you need to embed them yourself.

For more information, refer to mohamed hegazy's answer below for a more modern answer, or even this reddit comment for a short version.


As of 1.5.0 beta, TypeScript does not yet support Maps. It is not yet part of the roadmap, either.

The current best solution is an object with typed key and value (sometimes called a hashmap). For an object with keys of type string, and values of type number:

var arr : { [key:string]:number; } = {};

Some caveats, however:

  1. keys can only be of type string or number
  2. It actually doesn't matter what you use as the key type, since numbers/strings are still accepted interchangeably (only the value is enforced).

With the above example:

// OK:
arr["name"] = 1; // String key is fine
arr[0] = 0; // Number key is fine too

// Not OK:
arr[{ a: "a" }] = 2; // Invalid key
arr[3] = "name"; // Invalid value

Solution 2 - Javascript

See comment in: https://github.com/Microsoft/TypeScript/issues/3069#issuecomment-99964139

> TypeScript does not come with built in pollyfills. it is up to you to > decide which pollyfill to use, if any. you can use something like > es6Collection, > es6-shims, > corejs..etc. All the Typescript > compiler needs is a declaration for the ES6 constructs you want to > use. you can find them all in this lib > file. > > here is the relevant portion: > > > > interface Map { > clear(): void; > delete(key: K): boolean; > entries(): IterableIterator<[K, V]>; > forEach(callbackfn: (value: V, index: K, map: Map) => void, thisArg?: any): void; > get(key: K): V; > has(key: K): boolean; > keys(): IterableIterator; > set(key: K, value?: V): Map; > size: number; > values(): IterableIterator; > Symbol.iterator:IterableIterator<[K,V]>; > [Symbol.toStringTag]: string; > } > > interface MapConstructor { > new (): Map; > new (iterable: Iterable<[K, V]>): Map; > prototype: Map; > } > declare var Map: MapConstructor;

Solution 3 - Javascript

Here is an example:

this.configs = new Map<string, string>();
this.configs.set("key", "value");

Demo

Solution 4 - Javascript

Yes Map is now available in typescript.. if you look in lib.es6.d.ts, you will see the interface:

interface Map<K, V> {
  clear(): void;
  delete(key: K): boolean;
  forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void,thisArg?: any): void;
  get(key: K): V | undefined;
  has(key: K): boolean;
  set(key: K, value: V): this;
  readonly size: number;} 

Its great to use as a dictionary of string,object pairs.. the only annoyance is that if you are using it to assign values elsewhere with Map.get(key) the IDE like Code gives you problems about being possible undefined.. rather than creating a variable with an is-defined check .. simply cast the type (assuming you know for sure the map has the key-value pair)

class myclass {
   mymap:Map<string,object>
   ...
   mymap = new Map<string,object>()
   mymap.set("akey",AnObject)
   let objectref = <AnObject>mymap.get("akey")

Solution 5 - Javascript

> How do I declare an ES6 Map type in typescript?

You need to target --module es6. This is misfortunate and you can raise your concern here : https://github.com/Microsoft/TypeScript/issues/2953#issuecomment-98514111

Solution 6 - Javascript

As a bare minimum:

tsconfig:

 "lib": [
      "es2015"
    ]

and install a polyfill such as https://github.com/zloirock/core-js if you want IE < 11 support: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

Solution 7 - Javascript

Not sure if this is official but this worked for me in typescript 2.7.1:

class Item {
   configs: Map<string, string>;
   constructor () {
     this.configs = new Map();
   }
}

In simple Map<keyType, valueType>

Solution 8 - Javascript

With the lib config option your are able to cherry pick Map into your project. Just add es2015.collection to your lib section. When you have no lib config add one with the defaults and add es2015.collection.

So when you have target: es5, change tsconfig.json to:

"target": "es5",
"lib": [ "dom", "es5", "scripthost", "es2015.collection" ],

Solution 9 - Javascript

Typescript does not yet support Map.

ES6 Compatibility Table

Solution 10 - Javascript

Add "target": "ESNEXT" property to the tsconfig.json file.

{
    "compilerOptions": {
        "target": "ESNEXT" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnicksrandallView Question on Stackoverflow
Solution 1 - JavascriptzehView Answer on Stackoverflow
Solution 2 - Javascriptmohamed hegazyView Answer on Stackoverflow
Solution 3 - JavascriptArnaudView Answer on Stackoverflow
Solution 4 - JavascriptnphiasView Answer on Stackoverflow
Solution 5 - JavascriptbasaratView Answer on Stackoverflow
Solution 6 - JavascriptNikosView Answer on Stackoverflow
Solution 7 - JavascriptJonas TomangaView Answer on Stackoverflow
Solution 8 - JavascriptHolgerJerominView Answer on Stackoverflow
Solution 9 - JavascriptLogan TegmanView Answer on Stackoverflow
Solution 10 - JavascriptYasView Answer on Stackoverflow