Búsqueda de sitios web

Error Typescript TS2322 al usar tipos de búsqueda


Me estoy rompiendo la cabeza sobre por qué el siguiente código no compila:

interface Circle { type: "circle"; }
interface Rectangle { type: "rectangle"; }
type Shape = Circle | Rectangle;

interface Circle { type: "circle"; }
interface Rectangle { type: "rectangle"; }
type ShapeTemplate = {
  type: Shape["type"];
};

const fromTemplate = (template: ShapeTemplate): Shape => template;

Se rompe con:

TS2322: Type 'ShapeTemplate' is not assignable to type 'Shape'. Type 'ShapeTemplate' is not assignable to type 'Rectangle'. Types of property 'type' are incompatible. Type '"circle" | "rectangle"' is not assignable to type '"rectangle"'. Type '"circle"' is not assignable to type '"rectangle"'.

Respuesta #1

La respuesta corta es que, en general, es demasiado complejo para que el compilador de TypeScript reduzca {x: A} | {x: B} a {x: A|B}.

Puedes leer sobre esto en la discusión en Microsoft/TypeScript#7553 y en algunos otros lugares que no puedo encontrar en este momento. (Edición: también ver Microsoft/TypeScript#18230). Creo que los mantenedores del lenguaje no consideran que valga la pena intentar implementar esto, porque la mayoría de las veces no es útil en la práctica; los tipos que la gente realmente usa generalmente tienen más de una propiedad, y tan pronto como tienes {x: A, y: P } | {x: B, y: Q}, una reducción a algo como {x: A|B, y: P|Q} no es válida.

En la práctica, la solución aquí es simplemente afirmar que un ShapeTemplate es asignable a Shape, así:

const fromTemplate = (template: ShapeTemplate): Shape => template as Shape;

¡Espero que eso ayude; buena suerte!

Artículos relacionados