if (typeof Map === "undefined") { interface IKeyValuePair { key: K; value: V; } class AtomMap { public get size(): number { return this.map.length; } private map: Array> = []; public clear(): void { this.map.length = 0; } public delete(key: K): boolean { return this.map.remove((x) => x.key === key); } public forEach(callbackfn: (value: V, key: K, map: Map) => void, thisArg?: any): void { for (const iterator of this.map) { callbackfn.call(thisArg, iterator.value, iterator.key, this); } } public get(key: K): V { const item = this.getItem(key, false); return item ? item.value : undefined; } public has(key: K): boolean { return this.map.find((x) => x.key === key) != null; } public set(key: K, value: V): this { const item = this.getItem(key, true); item.value = value; return this; } // public [Symbol.iterator](): IterableIterator<[K, V]> { // throw new Error("Method not implemented."); // } // public keys(): IterableIterator { // throw new Error("Method not implemented."); // } // public values(): IterableIterator { // throw new Error("Method not implemented."); // } // public get [Symbol.toStringTag](): string { // return "[Map]"; // } private getItem(key: K, create: boolean = false): IKeyValuePair { for (const iterator of this.map) { if (iterator.key === key) { return iterator; } } if (create) { const r = { key, value: undefined }; this.map.push(r); return r; } } } // tslint:disable-next-line:no-string-literal (window as any)["Map"] = AtomMap; } declare global { // tslint:disable-next-line:interface-name interface Map { getOrCreate(key: K, factory: (key: K) => V): V; } } // tslint:disable-next-line:only-arrow-functions Map.prototype.getOrCreate = function(key: any, factory: (key: any) => any): any { let item = this.get(key); if (item === undefined) { item = factory(key); this.set(key, item); } return item; }; export default Map;