Peta ES6 dalam naskah


173

Saya membuat kelas dalam naskah yang memiliki properti yang merupakan ES6 (ECMAscript 2016) Peta seperti:

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

Bagaimana cara menyatakan tipe Peta ES6 dalam naskah?

Jawaban:


233

EDIT (5 Jun 2019): Sementara gagasan bahwa "TypeScript mendukung Mapsecara asli" masih benar, karena versi 2.1 TypeScript mendukung sesuatu yang disebut Record.

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

Sayangnya parameter generik pertama (tipe kunci) masih belum sepenuhnya dihormati: bahkan dengan stringtipe, sesuatu seperti peopleA[0](a number) masih valid.


EDIT (25 Apr 2016): Jawaban di bawah ini sudah tua dan tidak boleh dianggap sebagai jawaban terbaik. TypeScript memang mendukung Maps "secara native" sekarang, jadi ini hanya memungkinkan ES6 Maps untuk digunakan ketika outputnya adalah ES6. Untuk ES5, itu tidak menyediakan polyfill; Anda harus menanamkannya sendiri.

Untuk informasi lebih lanjut, lihat jawaban mohamed hegazy di bawah ini untuk jawaban yang lebih modern, atau bahkan komentar reddit ini untuk versi singkat.


Pada versi 1.5.0 beta, TypeScript belum mendukung Maps . Ini juga belum menjadi bagian dari peta jalan .

Solusi terbaik saat ini adalah objek dengan kunci dan nilai yang diketik (kadang-kadang disebut hashmap). Untuk objek dengan kunci tipe string, dan nilai tipe number:

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

Namun, beberapa peringatan:

  1. kunci hanya dapat bertipe stringataunumber
  2. Sebenarnya tidak masalah apa yang Anda gunakan sebagai tipe kunci, karena angka / string masih diterima secara bergantian (hanya nilainya yang dipaksakan).

Dengan contoh di atas:

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

3
Lalu bagaimana Anda mengulangi properti di peta? Ketika saya melakukan arr.values ​​(), saya mendapatkan "Nilai 'properti' tidak ada pada tipe ..."
Vern Jensen

Tidak sama dengan values(), saya akan melakukannya for (var key in arr) ... arr[key]atau for...of. Solusi lain (yang lebih dan lebih realistis saat ini dan akan sementara waktu untuk banyak hal) adalah dengan menggunakan corejs .
zeh

Bahkan ketika saya menggunakan kunci apa pun sebagai properti di peta yang dinyatakan dengan cara ini, saya mendapatkan "Properti 'apa pun' yang tidak ada pada tipe"
rakslice

Saya menggunakan kelas peta untuk membangun satu, tetapi bahkan jika saya lakukan map Map<string,string>=new Map<string,string>()ketika saya melakukannya map.set(something) saya mendapatkan pengecualian map is undefined, apakah ada cara lain untuk menginisialisasi itu?
mautrok

1
Saat menargetkan ES5, bahkan dengan polyfill, Anda tidak dapat menggunakan fitur tertentu - lihat github.com/Microsoft/TypeScript/issues/6842
Ondra Žižka

128

Lihat komentar di: https://github.com/Microsoft/TypeScript/issues/3069#issuecomment-99964139

TypeScript tidak datang dengan pollyfill bawaan. Terserah Anda untuk memutuskan pollyfill mana yang akan digunakan, jika ada. Anda dapat menggunakan sesuatu seperti es6Collection , es6-shims , corejs ..etc. Semua kebutuhan kompiler naskah adalah deklarasi untuk konstruksi ES6 yang ingin Anda gunakan. Anda dapat menemukan semuanya di file lib ini .

di sini adalah bagian yang relevan:

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;

3
Saat menargetkan ES5, bahkan dengan polyfill, Anda tidak dapat menggunakan fitur tertentu - lihat github.com/Microsoft/TypeScript/issues/6842
Ondra Žižka


30

Ya Peta sekarang tersedia dalam naskah .. jika Anda melihat di lib.es6.d.ts, Anda akan melihat antarmuka:

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

Sangat bagus untuk digunakan sebagai kamus string, pasangan objek .. satu-satunya gangguan adalah jika Anda menggunakannya untuk menetapkan nilai di tempat lain dengan Map.get (kunci) IDE seperti Kode memberi Anda masalah tentang kemungkinan tidak terdefinisi .. daripada membuat variabel dengan tanda centang yang ditentukan .. cukup masukkan tipe (dengan asumsi Anda tahu pasti peta memiliki pasangan kunci-nilai)

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



4

Tidak yakin apakah ini resmi tetapi ini berfungsi untuk saya dalam skrip 2.7.1:

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

Secara sederhana Map<keyType, valueType>


3

Dengan opsi lib config, Anda dapat memilih cherry Map ke dalam proyek Anda. Cukup tambahkan es2015.collectionke bagian lib Anda. Ketika Anda tidak memiliki lib config, tambahkan satu dengan default dan tambahkanes2015.collection .

Jadi ketika Anda memiliki target: es5, ubah tsconfig.json ke:

"target": "es5",
"lib": [ "dom", "es5", "scripthost", "es2015.collection" ],


0

Tambahkan "target": "ESNEXT"properti ke tsconfig.jsonfile.

{
    "compilerOptions": {
        "target": "ESNEXT" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.