javascript - ES6 Map i Typescript


Jag skapar en klass i TypeScript som har en egenskap som är en ES6 (ECMAscript 2016) Map på följande sätt:

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

Hur deklarerar jag en ES6 Map-typ i TypeScript?

Svar #1

REDIGERA (5 juni 2019): Även om idén att "TypeScript stöder Map nativt" fortfarande är sann, stödjer TypeScript sedan version 2.1 något som kallas Record.

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

Tyvärr respekteras fortfarande inte den första generiska parametern (nyckeltyp) fullt ut: även med en string-typ är något som peopleA[0] (en number) fortfarande giltigt.


REDIGERA (25 apr 2016): Svaret nedan är gammalt och bör inte anses vara det bästa svaret. TypeScript stöder nu kartor "nativt", så det tillåter helt enkelt att ES6-kartor används när utdata är ES6. För ES5 tillhandahåller det inga polyfiller; du behöver bädda in dem själv.

För mer information, hänvisa till Mohamed Hegazys svar nedan för ett mer modernt svar, eller till och med denna Reddit-kommentar för en kort version.


Från och med 1.5.0 beta stöder TypeScript ännu inte Maps. Det är ännu inte en del av färdplanen heller.

Den nuvarande bästa lösningen är ett objekt med typade nycklar och värden (ibland kallat en hashmap). För ett objekt med nycklar av typen string och värden av typen number:

var arr : { [key:string]:number; } = {};

Några varningar, dock:

  1. nycklar kan endast vara av typen string eller number
  2. Det spelar faktiskt ingen roll vilken typ av nyckel du använder, eftersom siffror/strängar fortfarande accepteras omväxlande (endast värdet är tvingande).

Med exemplet ovan:

// 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

Svar #2

Se kommentar på: https://github.com/Microsoft/TypeScript/issues/3069#issuecomment-99964139

TypeScript levereras inte med inbyggda polyfills. Det är upp till dig att bestämma vilken polyfill du vill använda, om någon. Du kan använda något som es6Collection, es6-shims, corejs..etc. Allt som TypeScript-kompilatorn behöver är en deklaration för de ES6-konstruktioner du vill använda. Du kan hitta dem alla i denna lib-fil.

här är den relevanta delen:

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;

Svar #3

Här är ett exempel:

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

Demo

Svar #4

Ja, Map finns nu tillgänglig i TypeScript.. om du tittar i lib.es6.d.ts kommer du att se gränssnittet:

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

Det är fantastiskt att använda som en ordlista för sträng-, objekt-par.. det enda irritationsmomentet är att om du använder den för att tilldela värden någon annanstans med Map.get(key) så ger IDE:n som Code dig problem om att det kan vara odefinierat.. istället för att skapa en variabel med en is-defined-kontroll .. kasta helt enkelt typen (förutsatt att du vet säkert att kartan har nyckel-värde-paret)

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

Svar #5

Hur deklarerar jag en ES6 Map-typ i TypeScript?

Du behöver rikta in dig på --module es6. Detta är olyckligt och du kan framföra din oro här: https://github.com/Microsoft/TypeScript/issues/2953#issuecomment-98514111

Svar #6

Som ett absolut minimum:

tsconfig:

 "lib": [
      "es2015"
    ]

och installera en polyfill såsom https://github.com/zloirock/core-js om du vill ha stöd för IE < 11: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

Svar #7

Inte säker på om detta är officiellt, men detta fungerade för mig i TypeScript 2.7.1:

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

I enkel Map<keyType, valueType>

Relaterade artiklar