microsoft / microsoft/TypeScript
Index type distributes over intersections too eagerly
Ouverte
Personne n'a encore pris cette issue.
Domain: Indexed Access Types
Help Wanted
Possible Improvement
- Langage dominant
- Go
- Étoiles
- 111k
- Forks
- 14.3k
- Merge moyen
- 2 j 4 h
- PR mergées (30 j)
- 132
Description
🔎 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]: ... })
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 la reproduction TypeScript Playground liée et suivez le chemin du checker pour indexed access, keyof, intersections et Omit. Comparez l’appel du callback annoté avec le type de fonction équivalent écrit explicitement. C’est terminé lorsque l’appel inféré enq.emit.increased refuse une chaîne pour upBy, avec un test de régression couvrant le cas signalé.
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é
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 42/100