Open
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
T
gets instantiated withExtractEventsFromPayloadMap<{ increased: { upBy: number; }; decreased: { downBy: number; }; }
- but now
keyof ...
returns only shared keys of this union - the only shared key is
type
so thisExclude
gets computed asnever
(Exclude<"type", "type">
) - and the final parameter type of
enq.emit.increased
gets computed as just{}
(from{ [K in never]: ... }
)