Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

168
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda