Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

167
Vistas
Typescript Omit seems to transform an union into an intersection

I have this type

type Cartesian = { kind: 'cartesian'; x: number; y: number; }
type Polar = { kind: 'polar'; angle: number; distance: number }
type Movement = { name: string } & (Cartesian | Polar);

that I can use like this

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 });

but for some reason, I can't use it like this

const unnamedMove = (unnamedMovement: Omit<Movement, 'name'>) => {
    move({ name: 'default', ...unnamedMovement })
}

because TS throws a 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, distance

I don't understand this.

If I am not mistaken Omit<Movement, 'name'> should be equivalent to the union type Cartesian | Polar, which would make { name: 'default', ...unnamedMovement } a Movement, and all things should work.

However, it looks like TS infers Omit<Movement, 'name'> as if it was the union type Cartesian & Polar, thus the error.

Is it a bug or a mistake from my part?

playground link

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

You probably want Distributive conditional types. From the docs

When conditional types act on a generic type, they become distributive when given a union type.

This means that you can declare something like this

type DOmit<T, K extends string> = T extends any
  ? Omit<T, K>
  : never;

and then use it like this

const unnamedMove = (unnamedMovement: DOmit<Movement, "name">) => {
    move({ name: 'default', ...unnamedMovement })
}

Playground here

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda