number - typescript variables




¿Imponer el tipo de los miembros indexados de un objeto Typescript? (4)

Basándose en la respuesta de @shabunc, esto permitiría aplicar la clave o el valor, o ambos, para que sea lo que quiera aplicar.

type IdentifierKeys = 'my.valid.key.1' | 'my.valid.key.2';
type IdentifierValues = 'my.valid.value.1' | 'my.valid.value.2';

let stuff = new Map<IdentifierKeys, IdentifierValues>();

También debería funcionar usando enum lugar de una definición de type .

Me gustaría almacenar un mapeo de cadena -> cadena en un objeto de TypeScript, y hacer que todas las claves se correlacionen con las cadenas. Por ejemplo:

var stuff = {};
stuff["a"] = "foo";   // okay
stuff["b"] = "bar";   // okay
stuff["c"] = false;   // ERROR!  bool != string

¿Hay alguna forma de que haga cumplir que los valores deben ser cadenas (o el tipo que sea ...)?


La respuesta de @Ryan Cavanaugh está totalmente bien y sigue siendo válida. Todavía vale la pena agregar que a partir del otoño de 2016, cuando podemos afirmar que ES6 es compatible con la mayoría de las plataformas, casi siempre es mejor adherirse a Map cada vez que necesite asociar algunos datos con alguna clave.

Cuando escribimos let a: { [s: string]: string; } let a: { [s: string]: string; } tenemos que recordar que después de que se compile el texto mecanografiado no hay datos de tipo, solo se usa para compilar. Y {[s: cadena]: cadena; } se compilará solo a {}.

Dicho eso, incluso si escribes algo así como:

class TrickyKey  {}

let dict: {[key:TrickyKey]: string} = {}

Esto simplemente no compilará (incluso para el target es6 , obtendrá el error TS1023: An index signature parameter type must be 'string' or 'number'.

Prácticamente está limitado con la cadena o el número como clave potencial, por lo que no tiene sentido imponer la verificación de tipo aquí, especialmente teniendo en cuenta que cuando js intenta acceder a la clave por número, la convierte en cadena.

Por lo tanto, es bastante seguro asumir que la mejor práctica es usar Map incluso si las claves son de cadena, así que me quedaría con:

let staff: Map<string, string> = new Map();

Una actualización rápida: desde Typescript 2.1 hay un tipo incorporado Record<T, K> que actúa como un diccionario.

Un ejemplo de documentos:

// For every properties K of type T, transform it to U
function mapObject<K extends string, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U>

const names = { foo: "hello", bar: "world", baz: "bye" };
const lengths = mapObject(names, s => s.length);  // { foo: number, bar: number, baz: number }

Documentación de TypeScript 2.1 en el Record<T, K>

La única desventaja que veo al usar esto sobre {[key: T]:K es que puedes codificar información útil sobre qué tipo de clave estás usando en lugar de "clave", por ejemplo, si tu objeto solo tenía claves principales que podrías indicar. eso me gusta: {[prime: number]: yourType} .

Aquí hay una expresión regular que escribí para ayudar con estas conversiones. Esto solo convertirá los casos donde la etiqueta es "clave". Para convertir otras etiquetas simplemente cambie el primer grupo de captura:

Buscar: \{\s*\[(key)\s*(+\s*:\s*(\w+)\s*\]\s*:\s*([^\}]+?)\s*;?\s*\}

Reemplazar: Record<$2, $3>


var stuff: { [s: string]: string; } = {};
stuff['a'] = ''; // ok
stuff['a'] = 4;  // error

// ... or, if you're using this a lot and don't want to type so much ...
interface StringMap { [s: string]: string; }
var stuff2: StringMap = { };
// same as above




typescript