Bản đồ ES6 trong Bản đánh máy


173

Tôi đang tạo một lớp trong bản thảo có thuộc tính là Bản đồ ES6 (ECMAscript 2016) như sau:

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

Làm cách nào để khai báo loại Bản đồ ES6 trong bản thảo?

Câu trả lời:


233

EDIT (ngày 5 tháng 6 năm 2019): Mặc dù ý tưởng rằng "TypeScript hỗ trợ Mapnguyên bản" vẫn đúng, vì phiên bản 2.1 TypeScript hỗ trợ một cái gì đó được gọi Record.

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

Thật không may, tham số chung đầu tiên (loại khóa) vẫn chưa được tuân thủ đầy đủ: ngay cả với một stringloại, một cái gì đó như peopleA[0](a number) vẫn hợp lệ.


EDIT (ngày 25 tháng 4 năm 2016): Câu trả lời dưới đây đã cũ và không nên được coi là câu trả lời tốt nhất. TypeScript hiện hỗ trợ Bản đồ "nguyên bản", do đó, nó chỉ đơn giản cho phép Bản đồ ES6 được sử dụng khi đầu ra là ES6. Đối với ES5, nó không cung cấp polyfill; bạn cần phải tự nhúng chúng.

Để biết thêm thông tin, hãy tham khảo câu trả lời của mohamed hegazy dưới đây để có câu trả lời hiện đại hơn, hoặc thậm chí bình luận reddit này cho một phiên bản ngắn.


Kể từ bản 1.5.0 beta, TypeScript chưa hỗ trợ Bản đồ . Nó cũng không phải là một phần của lộ trình .

Giải pháp tốt nhất hiện tại là một đối tượng có khóa và giá trị được gõ (đôi khi được gọi là hashmap). Đối với một đối tượng có khóa loại stringvà giá trị loại number:

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

Một số hãy cẩn thận, tuy nhiên:

  1. Các khóa chỉ có thể là loại stringhoặcnumber
  2. Thực tế không có vấn đề gì khi bạn sử dụng làm loại khóa, vì số / chuỗi vẫn được chấp nhận thay thế cho nhau (chỉ giá trị được thi hành).

Với ví dụ trên:

// 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
Làm thế nào để bạn lặp lại các thuộc tính trong bản đồ? Khi tôi thực hiện Array.values ​​(), tôi nhận được "Giá trị 'thuộc tính' không tồn tại trên loại ..."
Vern Jensen

Không giống như values(), tôi sẽ làm for (var key in arr) ... arr[key]hoặc for...of. Giải pháp khác (hiện đang ngày càng thực tế hơn và sẽ có một thời gian cho rất nhiều thứ) là sử dụng corejs .
zeh

Trong thực tế, khi tôi sử dụng bất kỳ khóa nào làm tài sản trên bản đồ được khai báo theo cách này, tôi nhận được "Tài sản" bất cứ thứ gì "không tồn tại trên loại"
rakslice 19/03/2016

Tôi đang sử dụng lớp bản đồ để xây dựng một lớp, nhưng ngay cả khi tôi làm map Map<string,string>=new Map<string,string>()khi tôi map.set(something) gặp một ngoại lệ map is undefined, có cách nào khác để khởi tạo nó không?
mautrok

1
Khi nhắm mục tiêu ES5, ngay cả với polyfill, bạn không thể sử dụng một số tính năng nhất định - xem github.com/Microsoft/TypeScript/issues/6842
Ondra ižka

128

Xem bình luận trong: https://github.com/Microsoft/TypeScript/issues/3069#issuecomment-99964139

TypeScript không đi kèm với pollyfill tích hợp. tùy thuộc vào bạn quyết định sử dụng pollyfill nào, nếu có. bạn có thể sử dụng một cái gì đó như es6Collection , es6-shims , corejs ..etc . Tất cả các trình biên dịch Typecript cần là một khai báo cho các cấu trúc ES6 mà bạn muốn sử dụng. bạn có thể tìm thấy tất cả trong tập tin lib này .

đây là phần có liên quan:

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
Khi nhắm mục tiêu ES5, ngay cả với polyfill, bạn không thể sử dụng một số tính năng nhất định - xem github.com/Microsoft/TypeScript/issues/6842
Ondra ižka


30

Có Bản đồ hiện có sẵn trong bản thảo .. nếu bạn xem trong lib.es6.d.ts, bạn sẽ thấy giao diện:

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

Thật tuyệt khi sử dụng làm từ điển chuỗi, cặp đối tượng .. điều khó chịu duy nhất là nếu bạn đang sử dụng nó để gán giá trị ở nơi khác với Map.get (khóa) thì IDE như Code cung cấp cho bạn các vấn đề về việc không thể xác định được .. thay vì tạo một biến với một kiểm tra được xác định .. chỉ cần bỏ kiểu (giả sử bạn biết chắc rằng bản đồ có cặp khóa-giá trị)

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



4

Không chắc đây có phải là chính thức hay không nhưng điều này có hiệu quả với tôi trong bản thảo 2.7.1:

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

Trong đơn giản Map<keyType, valueType>


3

Với tùy chọn lib config, bạn có thể chọn Bản đồ vào dự án của mình. Chỉ cần thêm es2015.collectionvào phần lib của bạn. Khi bạn không có lib config, hãy thêm một cái với mặc định và thêmes2015.collection .

Vì vậy, khi bạn có mục tiêu: es5, hãy thay đổi tsconfig.json thành:

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


0

Thêm "target": "ESNEXT"tài sản vào tsconfig.jsontập tin.

{
    "compilerOptions": {
        "target": "ESNEXT" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.