249

我正在 typescript 中创建一个类,它的属性是 ES6 (ECMAscript 2016) Map,如下所示:

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

如何在 typescript 中声明 ES6 Map 类型?

4

10 回答 10

335

编辑(2019 年 6 月 5 日):虽然“TypeScript 原生支持”的想法Map仍然正确,因为 2.1 版 TypeScript 支持名为Record.

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

不幸的是,第一个泛型参数(键类型)仍未得到完全尊重:即使使用类型, (a ) 之类的string东西仍然有效。peopleA[0]number


编辑(2016 年 4 月 25 日):下面的答案是旧的,不应被视为最佳答案。TypeScript 现在确实“原生地”支持 Maps,因此它只允许在输出为 ES6 时使用 ES6 Maps。对于 ES5,它不提供 polyfill;你需要自己嵌入它们。

有关更多信息,请参阅下面的 mohamed hegazy 的答案以获得更现代的答案,或者甚至参考此 reddit 评论以获得简短版本。


从 1.5.0 beta 开始,TypeScript 还不支持Maps。它也不是路线图的一部分。

当前的最佳解决方案是具有类型化键和值的对象(有时称为哈希图)。对于具有 type 键和 typestring值的对象number

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

然而,一些警告:

  1. 键只能是类型stringnumber
  2. 实际上,您使用什么作为键类型并不重要,因为数字/字符串仍然可以互换接受(仅强制执行值)。

用上面的例子:

// 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
于 2015-05-03T21:42:16.140 回答
130

见评论:https ://github.com/Microsoft/TypeScript/issues/3069#issuecomment-99964139

TypeScript 没有内置 pollyfills。如果有的话,由你决定使用哪个 pollyfill。你可以使用类似 es6Collectiones6-shimscorejs ..等的东西。Typescript 编译器需要的只是一个你想要使用的 ES6 结构的声明。你可以在这个 lib 文件中找到它们。

这是相关部分:

interface Map<K, V> {
    clear(): void;
    delete(key: K): boolean;
    entries(): IterableIterator<[K, V]>;
    forEach(callbackfn: (value: V, index: K, map: Map<K, V>) => void, thisArg?: any): void;
    get(key: K): V;
    has(key: K): boolean;
    keys(): IterableIterator<K>;
    set(key: K, value?: V): Map<K, V>;
    size: number;
    values(): IterableIterator<V>;
    [Symbol.iterator]():IterableIterator<[K,V]>;
    [Symbol.toStringTag]: string;
}

interface MapConstructor {
    new <K, V>(): Map<K, V>;
    new <K, V>(iterable: Iterable<[K, V]>): Map<K, V>;
    prototype: Map<any, any>;
}
declare var Map: MapConstructor;
于 2015-05-07T21:34:21.557 回答
85

这是一个例子:

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

演示

于 2017-07-26T03:33:14.253 回答
47

是的,Map 现在可以在 typescript 中使用了。如果您查看 lib.es6.d.ts,您将看到界面:

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;} 

它非常适合用作字符串、对象对的字典。唯一的烦恼是,如果您使用它通过Map.get(key)在其他地方分配值,则像 Code 这样的 IDE 会给您带来可能未定义的问题.. 而不是使用 is-defined 检查创建变量.. 只需转换类型(假设您确定地图具有键值对)

class myclass {
   mymap:Map<string,object>
   ...
   mymap = new Map<string,object>()
   mymap.set("akey",AnObject)
   let objectref = <AnObject>mymap.get("akey")
于 2018-06-12T22:19:38.917 回答
14

如何在 typescript 中声明 ES6 Map 类型?

您需要针对--module es6. 这是不幸的,您可以在这里提出您的担忧:https ://github.com/Microsoft/TypeScript/issues/2953#issuecomment-98514111

于 2015-05-03T23:36:11.110 回答
11

至少:

配置:

 "lib": [
      "es2015"
    ]

如果您想要 IE < 11 支持,安装 polyfill,例如https://github.com/zloirock/core-js:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects /地图

于 2017-01-17T11:41:39.853 回答
6

不确定这是否是官方的,但这在 typescript 2.7.1 中对我有用:

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

在简单的Map<keyType, valueType>

于 2018-03-03T14:50:26.750 回答
4

使用lib config 选项,您可以将 Map 选择到您的项目中。只需添加es2015.collection到您的 lib 部分。当您没有 lib 配置时,添加一个默认值并添加es2015.collection.

因此,当您有目标:es5 时,将 tsconfig.json 更改为:

"target": "es5",
"lib": [ "dom", "es5", "scripthost", "es2015.collection" ],
于 2018-09-12T09:51:53.357 回答
2

Typescript 还不支持Map.

ES6 兼容性表

于 2015-05-03T21:28:53.803 回答
1

"target": "ESNEXT"属性添加到tsconfig.json文件中。

{
    "compilerOptions": {
        "target": "ESNEXT" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    }
}
于 2018-01-05T16:50:24.053 回答