typescript中的 ES6 地图

IT技术 javascript typescript typescript1.5
2021-02-02 06:30:56

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

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

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

6个回答

编辑(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](a number)这样的东西仍然有效。


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

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


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

当前最好的解决方案是具有类型化键和值的对象(有时称为哈希图)。对于键为 typestring且值为 type 的对象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() 时,我得到“类型上不存在属性‘值’...”
2021-03-27 06:30:56
事实上,当我在以这种方式声明的地图上使用任何键作为属性时,我得到“类型上不存在任何属性”
2021-03-28 06:30:56
Record 类型正是我需要替换 Map 的类型!没想到有这个功能,谢谢!!
2021-03-28 06:30:56
values(), I'd do for (var key in arr) ... arr[key]or 不同for...of其他解决方案(现在越来越现实,很多事情都会有一段时间)是使用corejs
2021-04-03 06:30:56
以 ES5 为目标时,即使使用 polyfill,您也无法使用某些功能 - 请参阅 github.com/Microsoft/TypeScript/issues/6842
2021-04-08 06:30:56

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

TypeScript 没有内置的 pollyfill。如果有的话,由您来决定使用哪种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;
以 ES5 为目标时,即使使用 polyfill,您也无法使用某些功能 - 请参阅github.com/Microsoft/TypeScript/issues/6842
2021-03-19 06:30:56

下面是一个例子:

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

演示

@Zelphir 对于您的错误TS2304,请检查:stackoverflow.com/questions/39416691/...
2021-04-02 06:30:56

是的 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(键)喜欢代码的IDE提供了有关是可能未定义的问题...而不是创建一个带有 is-defined 检查的变量 .. 只需转换类型(假设您确定地图具有键值对)

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

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

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