将Typescript中的Map<string, string>转换为JSON字符串表示形式

14

我在Typescript中有一个Map<string, string>类型的变量:

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

我想将其转换为 JSON 字符串表示:

{"我想将其转换为 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);

我在控制台打印时也输出了{}


ro[ke] 应该是 ro[key],不确定是否为打字错误。 - James Hay
Map 类型来自哪里?是哪个库? - Titian Cernicova-Dragomir
ES6中的"Map"?尝试使用新的Map()。 - Lostfields
Object.fromEntries(mapObject); 可在 Node 12 及以上版本中使用。 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries - Pankaj Chimbalkar
这个回答解决了你的问题吗?在Javascript中将Map转换为JSON对象 - Pankaj Chimbalkar
6个回答

12

我最终放弃了使用es6 Map,转而使用TSMaptags.toJSON()在其中可用。


11

易读?不,但它能运行。

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

    return o; 
  }, {})
)

正如@james-hay指出的那样,您有一个可能会使对象为空的拼写错误。


2
使用[key, val]代替参数e,在我看来会更易读。 :-) - Paleo
是啊,我通常会忘记那个不错的新解构赋值 :-) 谢谢。 - Lostfields
不过它不会进行深层次的toString。 - barfuin

10

虽然它并没有直接回答你的问题:当我遇到同样的问题时,我重新考虑了我的Map的使用方式,转而使用普通的JavaScript对象。由于JSON总是需要字符串作为键,Map的一个主要优势(任何类型的键)已经失去了优势。

Map的另一个优点是它们允许一个漂亮的类型签名,例如Map<String,Array<String>>。但在这里,TypeScript的“索引签名”为普通的JavaScript对象提供了完全相同的功能,甚至还允许为键命名:

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

这个可以几乎像 Map 一样使用(当然,语法有所不同),并且在嵌套时可以直接转换为 JSON,甚至是深层嵌套的情况。我认为后者非常重要,特别是在将对象树转换为 JSON 时,其中的映射可能深嵌于其他任意对象和数组之中。

另外,TypeScript 还有类型 Record<K, T> 来处理这种情况:将普通对象用作带类型的映射表。在上面的示例中,我可以编写:

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

7

惊讶地发现这个还未被提及:

let m = new Map().set('tag', 'v1').set('foo', 'bar')

JSON.stringify(Object.fromEntries(m))

在我看来,这似乎是最易读的解决方案。


0
在使用带有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);

编程愉快!


-1

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接