Necesito pasar el objeto anidado como argumento del método. Todo funciona en línea, pero pasar la variable dará como resultado un error de TS porque, por ejemplo { a: 'x' } se convertirá en { a: string } en su lugar. La solución para eso es usar as const en esa variable. Pero esto no funciona en objetos con matrices, etc. Me veo obligado a usar 'as const' varias veces DENTRO de ese objeto, en lugar de hacer 'as const' al final. ¿Por qué?
type A = 'xxx' | 'yyy' | 'zzz' type Demo = { a: A, b: number, }[] const demoMethod = (demo: Demo) => { console.log(demo) } /* Example #1 - OK */ demoMethod([ { a: 'xxx', b: 111 }, { a: 'yyy', b: 222 }, { a: 'xxx', b: 333 }, ]) /* Example #2 - ERROR */ const demo2 = [ { a: 'xxx', b: 111 }, { a: 'yyy', b: 222 }, { a: 'xxx', b: 333 }, ] demoMethod(demo2) /* Example #3 - OK */ const demo3 = [ { a: 'xxx', b: 111 } as const, { a: 'yyy', b: 222 } as const, { a: 'xxx', b: 333 } as const, ] demoMethod(demo3) /* Example #4 - ERROR */ const demo4 = [ { a: 'xxx', b: 111 }, { a: 'yyy', b: 222 }, { a: 'xxx', b: 333 }, ] as const demoMethod(demo4)No tiene ningún sentido para mí que incluso ese ejemplo n. ° 1 y n. ° 2 sean 100% iguales, el n. ¿Hay alguna solución mejor para obligar a TS a tratar mi argumento const de la misma manera que el argumento en línea?
Editar: tenga en cuenta que he definido el tipo y el método solo en mis propósitos de ejemplo. En la vida real, este método proviene de un paquete externo y sin tipo exportado.
El ejemplo #2 no funciona porque la demo se infiere como { a: string; b: number; }[] . Claramente, esto no se puede asignar a Demo , que es { a: A; b: number; }[] . Debe decirle explícitamente a TypeScript que la demo es del tipo Demo con una anotación de tipo como dijo @Cr4zySheep, o usarla as :
// type annotation const demo2: Demo = [ { a: 'xxx', b: 111 }, { a: 'yyy', b: 222 }, { a: 'xxx', b: 333 }, ] as Demo; // or use 'as' demoMethod(demo2);A continuación se corrige el ejemplo n.º 4
Las matrices de solo lectura no se pueden asignar a matrices regulares.
Esto se debe a que las matrices regulares son mutables. Si proporciona una matriz inmutable a algo que espera una matriz mutable, eso claramente es una falta de coincidencia de tipos. Sin embargo, los arreglos regulares se pueden asignar a arreglos inmutables, porque los arreglos regulares no tienen que ser mutados.
type Demo = ReadonlyArray<{ a: A, b: number, }>;Así que aquí estaría la solución propuesta; solo use una matriz de solo lectura.
Como no tiene acceso al tipo, puede intentar recuperarlo usando Parámetros .
type a = Parameters<typeof demoMethod>[0]; // Which gives // type a = { // a: A; // b: number; //}[]¡Entonces use la anotación de tipo, por ejemplo!
Respuesta anterior
En lugar de usar as const , podrías hacer const demo5: Demo = ... .
Luego comprobará que el valor que le das a demo5 corresponde al tipo Demo .
const demo5: Demo = [ { a: 'xxx', b: 111 }, { a: 'abc', b: 222 }, // TypeError: Type '"abc"' is not assignable to type 'A'. ] En general, es mejor evitar const a = ... as Demo; porque Typescript no hará ninguna verificación y solo asumirá que a es del tipo Demo .
const a = 'Hello world!' as number; // Won't raise an error const a: number = 'Hello world!'; // Will raise a type error