【问题标题】:convert Typescript Map<string, string> to json string representation将 Typescript Map<string, string> 转换为 json 字符串表示
【发布时间】:2018-02-14 10:05:57
【问题描述】:

我在 typescript 中有一个 Map&lt;string, string&gt; 变量:

let m = Map<string, string>().set('tag', 'v1');

我想转成json字符串表示:

'{"tag": "v1"}'

我尝试了 3 种不同的方法。首先是使用m.toString()。其次是使用JSON.stringify(m)。两者都返回{}。我什至尝试先将Map 转换为javascript object,然后再转换为字符串:

function MapToString(map): string {
  let ro = {};
  Object.keys(map).forEach( key => {
    ro[key] = map[key];
  });
  return JSON.stringify(ro);
}

s = MapToString(m);

当我尝试在控制台中打印它时,它也返回了{}

【问题讨论】:

标签: javascript json typescript


【解决方案1】:

虽然这似乎是其他答案中指出的错字,但当 ES6 和 vanilla JS 在同一个项目中一起使用时,可能会出现此问题。 JS 无法识别 ES6 映射并将其转换为空对象“{}”。

一个快速的解决方法是在 JS 对象中持久化 ES6 映射时使用序列化器/反序列化器

ES6 到 JS

convertTSMapToJSObj(tsMap) {
    const jsObj = {};
    tsMap.forEach(function (value, key) {
        jsObj[key] = value;
    });
    return jsObj;
}

JS 到 ES6

convertJSObjToTSMap(jsObj) {
    const tsMap = new Map();
    const arrayOfMapEntries = new Map<any, any>(Object.entries(jsObj);
    for (const [key, value] of arrayOfMapEntries.entries()) {
        tsMap.set(key, value);
    }
    return tsMap;
}

【讨论】:

    【解决方案2】:

    在带有 lib es2015 的 Nativescript 中我可以做到:

    从对象到字符串:

    // no need to import JSON
    let fooInString = JSON.stringify(this.mapObject.subMap);
    

    从字符串到对象:

    // no need to import JSON
    let fooInObject = JSON.parse(fooInString);
    

    编码愉快!

    【讨论】:

      【解决方案3】:

      虽然它没有直接回答你的问题:当我遇到同样的问题时,我重新考虑了我对 Map 的使用并选择了纯 JavaScript 对象。由于 JSON 总是需要字符串作为键,因此 Map 的主要优势之一(任何类型的键)无论如何都会丢失。

      Map 的另一个优点是它们允许很好的类型签名,例如Map&lt;String, Array&lt;String&gt;&gt;。但是这里 TypeScript 的“索引签名”为纯 JavaScript 对象提供了这一点,甚至允许为键命名:

      interface CityLists {
          [postcode: string]: Array<string>
      };
      

      这几乎可以像 Map 一样使用(当然,使用不同的语法)并且它直接转换为 JSON 即使是嵌套的。我认为后者在您将对象树转换为 JSON 时非常重要,其中映射可以嵌套在其他任意对象和数组的深处。

      另外,TypeScript 还具有用于此用例的类型 Record&lt;K, T&gt;:用作类型化映射的普通对象。在上面的例子中,我可以这样写:

      let cityLists: Record<string, Array<string>>;
      cityLists["capitals"] = ["Rome", "Paris", "Berlin"];
      

      【讨论】:

        【解决方案4】:

        可读吗?不,但它有效

        JSON.stringify(
          Array.from(
            new Map().set('tag', 'v1').set('foo', 'bar').entries()
          )
          .reduce((o, [key, value]) => { 
            o[key] = value; 
        
            return o; 
          }, {})
        )
        

        就像@james-hay 指出的那样,您的拼写错误可能会使对象为空

        【讨论】:

        • 使用[key, val] 而不是e 参数,IMO 将更具可读性。 :-)
        • 是的,我通常会忘记那个不错的新解构分配 :-) 谢谢。
        • 不做 deep toString, tho.
        【解决方案5】:

        我最终放弃了使用 es6 Map 并切换到 TSMaptags.toJSON() 工作。

        【讨论】:

          猜你喜欢
          • 2011-02-01
          • 2019-05-31
          • 1970-01-01
          • 2020-12-26
          • 2016-07-29
          • 2013-05-24
          • 2014-01-29
          • 1970-01-01
          相关资源
          最近更新 更多