แผนที่ ES6 ใน typescript


173

ฉันกำลังสร้างคลาสใน typescript ที่มีคุณสมบัติที่เป็นแผนที่ ES6 (ECMAscript 2016) เช่น:

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

ฉันจะประกาศประเภทแผนที่ ES6 ใน typescript ได้อย่างไร

คำตอบ:


233

แก้ไข (5 มิถุนายน 2019)ขณะที่ความคิดที่ว่า "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) ยังคงใช้ได้


แก้ไข (25 เม.ย. 2559):คำตอบด้านล่างเก่าและไม่ควรพิจารณาคำตอบที่ดีที่สุด TypeScript รองรับ Maps "ดั้งเดิม" ในขณะนี้ดังนั้นเพียงแค่อนุญาตให้ใช้แผนที่ ES6 เมื่อมีการส่งออกเป็น ES6 สำหรับ ES5 นั้นไม่ได้ให้บริการ polyfills คุณต้องฝังมันด้วยตัวเอง

สำหรับข้อมูลเพิ่มเติมอ้างถึงคำตอบของ mohamed hegazy ด้านล่างสำหรับคำตอบที่ทันสมัยกว่าหรือแม้แต่ความคิดเห็น reddit นี้สำหรับรุ่นสั้น ๆ


ในฐานะของ 1.5.0 เบต้า typescript ยังไม่สนับสนุนแผนที่ มันยังไม่ได้เป็นส่วนหนึ่งของแผนการทำงานเช่นกัน

ทางออกที่ดีที่สุดในปัจจุบันคือวัตถุที่พิมพ์คีย์และค่า (บางครั้งเรียกว่า hashmap) สำหรับวัตถุที่มีคีย์ประเภทstringและค่าประเภทnumber:

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

คำเตือนบางอย่าง:

  1. ปุ่มสามารถเป็นประเภทเท่านั้นstringหรือnumber
  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

3
แล้วคุณจะย้ำคุณสมบัติในแผนที่ได้อย่างไร? เมื่อฉันทำ arr.values ​​() ฉันจะได้รับ "คุณสมบัติ" ค่า 'ไม่มีอยู่ในประเภท ... "
Vern Jensen

ไม่เหมือนกับvalues()ที่ฉันต้องการจะทำอย่างไรหรือfor (var key in arr) ... arr[key] for...ofวิธีการแก้ปัญหาอื่น ๆ (ซึ่งมีมากขึ้นและมีเหตุผลมากขึ้นในปัจจุบันและจะเป็นในขณะที่สำหรับสิ่งต่างๆมากมายก) คือการใช้corejs
zeh

ในความเป็นจริงเมื่อฉันใช้คีย์ใด ๆ เป็นคุณสมบัติบนแผนที่ที่ประกาศด้วยวิธีนี้ฉันจะได้รับ "คุณสมบัติ 'อะไรก็ตาม' ไม่มีอยู่ในประเภท"
rakslice

ฉันใช้คลาสแผนที่เพื่อสร้างคลาสหนึ่ง แต่แม้ว่าฉันจะทำอย่างไรmap Map<string,string>=new Map<string,string>()เมื่อmap.set(something) ฉันได้รับการยกเว้นmap is undefinedมีวิธีอื่นในการเริ่มต้นหรือไม่
mautrok

1
เมื่อกำหนดเป้าหมาย ES5 แม้จะมี polyfills คุณจะไม่สามารถใช้คุณสมบัติบางอย่างได้ - ดู github.com/Microsoft/TypeScript/issues/6842
Ondra Žižka

128

ดูความคิดเห็นใน: https://github.com/Microsoft/TypeScript/issues/3069#issuecomment-99964139

TypeScript ไม่ได้มาพร้อมกับ pollyfills ในตัว ขึ้นอยู่กับคุณที่จะตัดสินใจว่าควรใช้ pollyfill ใดหากมี คุณสามารถใช้สิ่งที่ต้องการ es6Collection , ES6-shims , corejs ..etc ความต้องการของคอมไพเลอร์ 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;

3
เมื่อกำหนดเป้าหมาย ES5 แม้จะมี polyfills คุณจะไม่สามารถใช้คุณสมบัติบางอย่างได้ - ดูgithub.com/Microsoft/TypeScript/issues/6842
Ondra Žižka


30

ใช่แผนที่พร้อมใช้งานใน 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 เช่นรหัสทำให้คุณมีปัญหาเกี่ยวกับความเป็นไปได้ที่ไม่ได้กำหนด .. มากกว่า การสร้างตัวแปรด้วยการตรวจสอบที่ถูกกำหนด .. เพียงแค่พิมพ์ (สมมติว่าคุณรู้ว่าแผนที่มีคู่ของคีย์ - ค่า)

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

12

ฉันจะประกาศประเภทแผนที่ ES6 ใน typescript ได้อย่างไร

--module es6คุณจำเป็นต้องกำหนดเป้าหมาย นี่เป็นเรื่องที่โชคร้ายและคุณสามารถแจ้งข้อกังวลของคุณได้ที่นี่: https://github.com/Microsoft/TypeScript/issues/2953#issuecomment-98514111



4

ไม่แน่ใจว่านี่เป็นทางการหรือไม่ แต่มันใช้ได้กับฉันใน typescript 2.7.1:

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

ในแบบง่าย ๆ Map<keyType, valueType>


3

ด้วยตัวเลือกการกำหนดค่าlibคุณจะสามารถเลือกแผนที่ในโครงการของคุณ เพียงเพิ่มes2015.collectionส่วน lib ของคุณ เมื่อคุณมีไม่มีใคร lib config การเพิ่มกับค่าเริ่มต้นes2015.collectionและเพิ่ม

ดังนั้นเมื่อคุณมีเป้าหมาย: es5 เปลี่ยน tsconfig.json เป็น:

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

1

typescript ยังไม่รองรับ Mapยังไม่สนับสนุน

ตารางความเข้ากันได้ของ ES6


4
หน้าบนวิกิของ typescript นี้ดูเหมือนจะบอกว่ามันรองรับ: typescript.codeplex.com/ ...
nicksrandall

2019 มิถุนายน - แผนที่ได้รับการสนับสนุน
yehonatan yehezkel

0

เพิ่ม"target": "ESNEXT"คุณสมบัติให้กับtsconfig.jsonไฟล์

{
    "compilerOptions": {
        "target": "ESNEXT" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.