tengo este tipo
type Cartesian = { kind: 'cartesian'; x: number; y: number; } type Polar = { kind: 'polar'; angle: number; distance: number } type Movement = { name: string } & (Cartesian | Polar);que puedo usar así
const move = (movement: Movement) => { /* whatever */ }; move({ name: 'top right', kind: 'cartesian', x: 10, y: 10 }); move({ name: 'left', kind: 'polar', angle: Math.PI, distance: 10 });pero por alguna razón, no puedo usarlo así
const unnamedMove = (unnamedMovement: Omit<Movement, 'name'>) => { move({ name: 'default', ...unnamedMovement }) }porque TS lanza un 2345:
Argument of type '{ kind: "cartesian" | "polar"; name: string; }' is not assignable to parameter of type 'Movement'. Type '{ kind: "cartesian" | "polar"; name: string; }' is not assignable to type '{ name: string; } & Polar'. Type '{ kind: "cartesian" | "polar"; name: string; }' is missing the following properties from type 'Polar': angle, distanceno entiendo esto
Si no me equivoco Omit<Movement, 'name'> debería ser equivalente al tipo de unión Cartesian | Polar , que convertiría a { name: 'default', ...unnamedMovement } en un Movement , y todo debería funcionar.
Sin embargo, parece que TS infiere Omit<Movement, 'name'> como si fuera el tipo de unión Cartesian & Polar , de ahí el error.
¿Es un error o un error de mi parte?
Probablemente desee tipos condicionales distributivos . de los documentos
When conditional types act on a generic type, they become distributive when given a union type.
Esto significa que puedes declarar algo como esto
type DOmit<T, K extends string> = T extends any ? Omit<T, K> : never;y luego usarlo así
const unnamedMove = (unnamedMovement: DOmit<Movement, "name">) => { move({ name: 'default', ...unnamedMovement }) }