microsoft / microsoft/TypeScript
Index type distributes over intersections too eagerly
Offen
Dieses Issue hat noch niemand übernommen.
Domain: Indexed Access Types
Help Wanted
Possible Improvement
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 2 T. 4 Std.
- Gemergte PRs (30 T.)
- 132
Beschreibung
🔎 Search Terms
index keyof indexed access deferred deferral instantiation
🕗 Version & Regression Information
- This is the behavior in every version I tried
⏯ Playground Link
💻 Code
type Values<T> = T[keyof T];
// transforms from "keyed object map" to a union
type ExtractEventsFromPayloadMap<T> = Values<{
[K in keyof T]: T[K] & { type: K };
}>;
type EnqueueObject<TEmittedEvent extends { type: PropertyKey }> = {
// creates proxy methods
emit: {
[K in TEmittedEvent["type"]]: (
payload: Omit<TEmittedEvent & { type: K }, "type">,
) => void;
};
};
type Exec<TEmitted extends { type: PropertyKey }> = (
enq: EnqueueObject<TEmitted>,
) => void;
declare function createStore<TEmitted>(definition: {
emits: {
[K in keyof TEmitted]: (payload: TEmitted[K]) => void;
};
exec: Exec<ExtractEventsFromPayloadMap<TEmitted>>;
}): any;
createStore({
emits: {
increased: (_: { upBy: number }) => {},
decreased: (_: { downBy: number }) => {},
},
exec: (enq) => {
enq.emit.increased({
upBy: "bazinga", // this should error!
});
const fn = enq.emit.increased;
// ^?
// this is just a copy of what is displayed as `enq.emit.increased`'s type
const exactSameTypeAsAbove: (
payload: Omit<
{ upBy: number } & { type: "increased" } & { type: "increased" },
"type"
>,
) => void = () => {};
exactSameTypeAsAbove({
upBy: "bazinga", // this one errors correctly
});
},
});
🙁 Actual behavior
There is no error on the annotated call
🙂 Expected behavior
It should error
Additional information about the issue
keyof (T & { type: K })gets normalized tokeyof T & "type"- that passed through
Exclude<X, "type">(withinOmit) is left asExclude<keyof T, "type">. - then
Tgets instantiated withExtractEventsFromPayloadMap<{ increased: { upBy: number; }; decreased: { downBy: number; }; } - but now
keyof ...returns only shared keys of this union - the only shared key is
typeso thisExcludegets computed asnever(Exclude<"type", "type">) - and the final parameter type of
enq.emit.increasedgets computed as just{}(from{ [K in never]: ... })
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 der verknüpften TypeScript Playground-Reproduktion und verfolge den Checker-Pfad für indexed access, keyof, intersections und Omit. Vergleiche den annotierten Callback-Aufruf mit dem äquivalent explizit geschriebenen Funktionstyp. Erledigt ist es, wenn der inferierte Aufruf enq.emit.increased einen String für upBy ablehnt und ein Regressionstest den gemeldeten Fall abdeckt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- typescript
- Bereich
- compilers
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 42/100