microsoft / microsoft/TypeScript

Interface extension with omit produce incoherent results: Omit<C | D, 'a'> !== Omit<C, 'a'> | Omit<D, 'a'>

Ouverte
#42,680 5 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Docs
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

Bug Report

🔎 Search Terms

wrong set theory omit

🕗 Version & Regression Information

ts-node-dev ver. 1.1.1 (using ts-node ver. 9.1.1, typescript ver. 4.1.3)

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about it
    • ts-node-dev ver. 1.1.1 (using ts-node ver. 9.1.1, typescript ver. 4.1.3)
    • Nightly
⏯ Playground Link

Playground link with relevant code

💻 Code
interface Basic {
  a: string;
  b: number;
}

interface BasicPlusC extends Basic {
  c: string;
}

interface BasicPlusD extends Basic {
  d: string;
}

type BasicPlusCOrD = BasicPlusC | BasicPlusD;

type BasicPlusCOrDMinusA = Omit<BasicPlusCOrD, 'a'>;

const getUnknown = (): BasicPlusCOrDMinusA => (
  Math.random() > .5 ?
    { b: 0, c: ""} // <-- Causes error
  : { b: 0, d: ""}
);

const getUnknownBis = (): Omit<BasicPlusC, 'a'> | Omit<BasicPlusD, 'a'> => (
  Math.random() > .5 ?
    { b: 0, c: ""}
  : { b: 0, d: ""}
);

const main = (): void => {
  getUnknown();
  getUnknownBis();
};

main();
🙁 Actual behavior

Running this code causes the following error:

[INFO] 21:02:26 ts-node-dev ver. 1.1.1 (using ts-node ver. 9.1.1, typescript ver. 4.1.3)
Compilation error in /home/fabio/Projects/aalto/fullstack_open_2020_part9/part_c_patientor/backend/src/delete_me.ts
[ERROR] 21:02:27 ⨯ Unable to compile TypeScript:
src/delete_me.ts:20:13 - error TS2322: Type '{ b: number; c: string; } | { b: number; d: string; }' is not assignable to type 'Pick<BasicPlusCOrD, "b">'.
  Type '{ b: number; c: string; }' is not assignable to type 'Pick<BasicPlusCOrD, "b">'.
    Object literal may only specify known properties, and 'c' does not exist in type 'Pick<BasicPlusCOrD, "b">'.

20     { b: 0, c: ""} // <-- Causes error
               ~~~~~
🙂 Expected behavior

I would have expected both functions, getUnknown and getUnknownBis to work correctly. This is because I'm expecting the typing system to follow the same rules as set theory. In this case I have one function, getUnknown, whose return type structure is ({ a, b, c } | ({ a, b, d, }) \ { a }) which means that the resulting structure should be in the form { b, c } | { b, d }.

In the other function, getUnknownBis, the return type structure is ({ a, b, c } \ { a }) | ({ a, b, d, }) \ { a }) which means that the resulting structure should be again in the form { b, c } | { b, d }.

Hence I would expect both to work in the same way, but it looks like the first function is only expecting to return { b }, instead of { b, c } | { b, d }. This makes me think that the type inference engine is doing { b, c } & { b, d } instead.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par le TypeScript Playground lié et l’exemple minimal de union/Omit, puis examinez comment le vérificateur de types évalue Omit lorsque son entrée est une union et comparez ce comportement aux formes distributives explicites. Le travail est considéré comme terminé lorsque les deux exemples de types de retour se comportent de manière équivalente, avec une couverture de régression pour les affectations signalées.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Bug
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
30/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.