Description
π Search Terms
inference nested contextual type reverse mapped type parameter
π Version & Regression Information
- This is the behavior in every version I tried
β― Playground Link
π» Code
type ActorRef<TInput> = {
create?: (input: TInput) => void;
};
declare function fromCreate<TInput>(
create: (input: TInput) => void,
): ActorRef<TInput>;
declare function setup1<
TActors extends Record<string, ActorRef<never>>,
>(impls: {
actors?: {
[K in keyof TActors]: TActors[K];
};
}): TActors;
const result1 = setup1({
actors: {
withInput: fromCreate((input: string) => {}),
withoutInput: fromCreate(() => {}),
},
});
result1;
// ^? const result1: { withInput: ActorRef<string>; withoutInput: ActorRef<unknown>; }
declare function setup2<
TActors extends Record<string, ActorRef<never>>,
>(impls: { actors?: TActors }): TActors;
const result2 = setup2({
actors: {
withInput: fromCreate((input: string) => {}),
withoutInput: fromCreate(() => {}),
},
});
result2;
// ^? const result2: { withInput: ActorRef<string>; withoutInput: ActorRef<never>; }
π Actual behavior
The only difference between those 2 calls is that TActors
of the outer setup
call is either iterated over (with Identity
-like mapped type) or not.
Yet when this "noop" iteration is involved we infer the constraint of the TInput
parameter in the nested fromCreate
call. When the iteration is not involved then we infer never
.
π Expected behavior
I'd expect both of those calls to behave identically.
Additional information about the issue
- without the iteration the contextual type for this inner call is
ActorRef<never>
whereas with the iteration it'sTActors["withoutInput"]
- without the iteration we successfully
inferTypes
usingInferencePriority.ReturnType
from the instantiatedcontextualType
but with the iteration we getsilentNeverType
forTActors
and thus alsosilentNeverType
for the whole indexed access. AsilentNeverType
is non-inferrable - One of those calls can gather inference candidates (and thus
ActorRef<never>
gets inferred) and the other one is not (so it defaults to its constraint).
It might not be worth fixing this. I figured out that it might still be interesting to raise this. Maybe a rule similar to the one introduced here could be introduced somewhere? A more specific type (depending on the variance of the type parameter) could be picked up from the constraint type and the type inferred using InferencePriority.ReturnType
. I'm not sure if that would work in practice though - just thinking out loud while writing, without giving this more thought π
Activity