javascript - Mapa ES6 en Typescript
Estoy creando una clase en TypeScript que tiene una propiedad que es un Map de ES6 (ECMAScript 2016) de la siguiente manera:
class Item {
configs: ????;
constructor () {
this.configs = new Map();
}
}
¿Cómo declaro un tipo Map de ES6 en TypeScript?
Respuesta #1
EDITAR (5 de junio de 2019): Aunque la idea de que "TypeScript soporta Map de manera nativa" sigue siendo cierta, desde la versión 2.1 TypeScript soporta algo llamado Record.
type MyMapLikeType = Record<string, IPerson>;
const peopleA: MyMapLikeType = {
"a": { name: "joe" },
"b": { name: "bart" },
};
Desafortunadamente, el primer parámetro genérico (tipo de clave) aún no se respeta completamente: incluso con un tipo string, algo como peopleA[0] (un number) sigue siendo válido.
EDITAR (25 de abril de 2016): La respuesta a continuación es antigua y no debería considerarse la mejor respuesta. TypeScript ahora admite Maps "de manera nativa", por lo que simplemente permite que se usen Maps de ES6 cuando la salida es ES6. Para ES5, no proporciona polyfills; necesitas incorporarlos tú mismo.
Para más información, consulta la respuesta de Mohamed Hegazy a continuación para una respuesta más moderna, o incluso este comentario de Reddit para una versión corta.
A partir de la versión 1.5.0 beta, TypeScript aún no admite Maps. Tampoco forma parte de la hoja de ruta.
La mejor solución actual es un objeto con clave y valor tipados (a veces llamado hashmap). Para un objeto con claves de tipo string y valores de tipo number:
var arr : { [key:string]:number; } = {};
Algunas advertencias, sin embargo:
- las claves solo pueden ser del tipo
stringonumber - En realidad, no importa qué uses como tipo de clave, ya que los números/cadenas todavía se aceptan de manera intercambiable (solo se aplica la restricción al valor).
Con el ejemplo anterior:
// 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
Respuesta #2
Ver comentario en: https://github.com/Microsoft/TypeScript/issues/3069#issuecomment-99964139
TypeScript no viene con polyfills incorporados. Depende de usted decidir qué polyfill usar, si es que usa alguno. Puede usar algo como es6Collection, es6-shims, corejs, etc. Todo lo que el compilador de TypeScript necesita es una declaración de los constructos de ES6 que desea usar. Puede encontrarlos todos en este archivo de biblioteca.
aquí está la porción relevante:
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;
Respuesta #3
Aquí hay un ejemplo:
this.configs = new Map<string, string>();
this.configs.set("key", "value");
Demostración
Respuesta #4
Sí, Map ahora está disponible en TypeScript.. si miras en lib.es6.d.ts, verás la interfaz:
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;}
Es genial usarlo como un diccionario de pares string-objeto. La única molestia es que si lo estás usando para asignar valores en otro lugar con Map.get(key), el IDE como Code te da problemas sobre la posibilidad de que sea indefinido. En lugar de crear una variable con una comprobación de si está definido, simplemente castea el tipo (asumiendo que sabes con seguridad que el mapa tiene el par clave-valor).
class myclass {
mymap:Map<string,object>
...
mymap = new Map<string,object>()
mymap.set("akey",AnObject)
let objectref = <AnObject>mymap.get("akey")
Respuesta #5
¿Cómo declaro un tipo Map de ES6 en TypeScript?
Necesitas apuntar a --module es6. Esto es desafortunado y puedes expresar tu preocupación aquí: https://github.com/Microsoft/TypeScript/issues/2953#issuecomment-98514111
Respuesta #6
Como mínimo:
tsconfig:
"lib": [
"es2015"
]
e instala un polyfill como https://github.com/zloirock/core-js si quieres soporte para IE < 11: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
Respuesta #7
No estoy seguro de si esto es oficial, pero esto me funcionó en TypeScript 2.7.1:
class Item {
configs: Map<string, string>;
constructor () {
this.configs = new Map();
}
}
En un simple Map<keyType, valueType>
