microsoft / microsoft/TypeScript
Interface extension with omit produce incoherent results: Omit<C | D, 'a'> !== Omit<C, 'a'> | Omit<D, 'a'>
Personne n'a encore pris cette issue.
- 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
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- 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