【问题标题】:ES6 Map in Typescript打字稿中的 ES6 地图
【发布时间】:2015-07-13 05:07:52
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript typescript typescript1.5


    【解决方案1】:

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

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

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


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

    有关更多信息,请参阅 mohamed hegazy's answer below 以获得更现代的答案,或者甚至 this reddit comment 以获得简短版本。


    从 1.5.0 测试版开始,TypeScript 还不支持Maps。它还不是roadmap 的一部分。

    当前最好的解决方案是具有类型化键和值的对象(有时称为哈希图)。对于具有string 类型的键和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
    

    【讨论】:

    • 那么你如何迭代地图中的属性呢?当我执行 arr.values() 时,我得到“类型上不存在属性‘值’……”
    • values() 不同,我会使用for (var key in arr) ... arr[key]for...of。其他解决方案(现在越来越现实,很多事情会持续一段时间)是使用corejs
    • 事实上,当我在以这种方式声明的地图上使用任何键作为属性时,我会得到“类型上不存在属性'whatever'”
    • 面向 ES5 时,即使使用 polyfill,您也无法使用某些功能 - 请参阅 github.com/Microsoft/TypeScript/issues/6842
    • Record 类型正是我替换 Map 所需要的!我不知道这存在,谢谢!!
    【解决方案2】:

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

    TypeScript 没有内置 pollyfills。由你决定 决定使用哪个 pollyfill,如果有的话。你可以使用类似的东西 es6Collection, es6-shims, corejs..等等。所有打字稿 编译器需要是你想要的 ES6 结构的声明 采用。你可以在this lib file找到它们。

    这里是相关部分:

    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;
    

    【讨论】:

    【解决方案3】:

    这是一个例子:

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

    Demo

    【讨论】:

    【解决方案4】:

    是的,现在可以在 typescript 中使用 Map。如果您查看 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) 在其他地方分配值,IDE 就像 Code 提供的您可能会遇到未定义的问题.. 而不是使用 is-defined 检查创建变量.. 只需转换类型(假设您确定地图具有键值对)

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

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

        至少:

        tsconfig:

         "lib": [
              "es2015"
            ]
        

        如果您想要 IE https://github.com/zloirock/core-js 之类的 polyfill:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

        【讨论】:

          【解决方案7】:

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

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

          简单的Map&lt;keyType, valueType&gt;

          【讨论】:

            【解决方案8】:

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

            所以当你有 target: es5 时,将 tsconfig.json 更改为:

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

            【讨论】:

              【解决方案9】:

              Typescript 还不支持Map

              ES6 Compatibility Table

              【讨论】:

              【解决方案10】:

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

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

              【讨论】:

                猜你喜欢
                • 2020-08-30
                • 2023-04-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-10-06
                • 2017-05-09
                • 2021-11-07
                • 2022-01-03
                相关资源
                最近更新 更多