microsoft / microsoft/TypeScript
Interface extension with omit produce incoherent results: Omit<C | D, 'a'> !== Omit<C, 'a'> | Omit<D, 'a'>
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 1 T. 19 Std.
- Gemergte PRs (30 T.)
- 117
Beschreibung
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.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit dem verlinkten TypeScript Playground und dem minimalen union/Omit-Beispiel. Untersuche anschließend, wie der Type Checker Omit bewertet, wenn seine Eingabe eine Union ist, und vergleiche dies mit den expliziten distributiven Formen. Als abgeschlossen gilt die Aufgabe, wenn sich die beiden Beispiele für Rückgabetypen äquivalent verhalten und eine Regressionstestabdeckung für die gemeldeten Zuweisungen vorhanden ist.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- typescript
- Bereich
- compilers
- Issue-Typ
- Bug
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 30/100