Quiero crear un tipo para un objeto con claves de string y valores arbitrarios. Por lo tanto, mi tipo deseado (llamémoslo Obj ) debería causar un error de tipo para el siguiente objeto obj porque su clave es de tipo number :
const obj: Obj = { 1: "foo" // I'd expect a TS error here because the key 1 is of type `number` and not `string` };¡Sin embargo, todos mis intentos no causan ningún error de TS! Aquí están mis tres intentos:
Record integrado (que utiliza implícitamente el operador in ): type Obj = Record<'1', any>; const obj: Obj = { 1: "foo" // TS error expected! ❌ };Record ): type Obj = { [key: string]: any }; const obj: Obj = { 1: "foo" // TS error expected! ❌ };Record personalizado con reasignación de teclas a través as : type MyRecord<K extends string, T> = { [P in K as string]: T; }; type Obj = MyRecord<string, any>; const obj: Obj = { 1: "foo" // TS error expected! ❌ };'1' no obliga a que la clave sea '1' , pero permite el número 1 : type Obj = Record<'1', any>; const obj: Obj = { 1: "foo" // TS error expected! ❌ };¿Es posible en general, o se debe a alguna propiedad de un objeto JavaScript que no es posible?
El 1 se coacciona a una string ( "1" ) cuando se define un objeto literal. No puede definir un objeto con teclas number :
const obj = { prop: 'value', 1: 'another value', }; for (const key in obj) { console.log(key, typeof key); }Por lapágina keyof del documento de TypeScript
Las claves de objeto de JavaScript siempre se coaccionan a una cadena, por lo que obj[0] siempre es lo mismo que obj["0"]
Entonces, de hecho, {1: "foo"} es igual que {"1": "foo"} .