Skip to content

Commit 07e36ce

Browse files
committed
Prefer returnMapper-based contextual type instantiations when candidates-based returns any/unknown
1 parent c069fbb commit 07e36ce

8 files changed

+1359
-1
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32612,7 +32612,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3261232612
if (inferenceContext && contextFlags! & ContextFlags.Signature && some(inferenceContext.inferences, hasInferenceCandidatesOrDefault)) {
3261332613
// For contextual signatures we incorporate all inferences made so far, e.g. from return
3261432614
// types as well as arguments to the left in a function call.
32615-
return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper);
32615+
const type = instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper);
32616+
if (!(type.flags & TypeFlags.AnyOrUnknown)) {
32617+
return type;
32618+
}
3261632619
}
3261732620
if (inferenceContext?.returnMapper) {
3261832621
// For other purposes (e.g. determining whether to produce literal types) we only
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
//// [tests/cases/compiler/returnTypeInferenceContextualParameterTypesInGenerator1.ts] ////
2+
3+
=== returnTypeInferenceContextualParameterTypesInGenerator1.ts ===
4+
interface Effect<out A> {
5+
>Effect : Symbol(Effect, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 0, 0))
6+
>A : Symbol(A, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 0, 17))
7+
8+
readonly _A: A;
9+
>_A : Symbol(Effect._A, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 0, 25))
10+
>A : Symbol(A, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 0, 17))
11+
}
12+
13+
declare function gen<Eff extends Effect<any>, AEff>(
14+
>gen : Symbol(gen, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 2, 1))
15+
>Eff : Symbol(Eff, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 4, 21))
16+
>Effect : Symbol(Effect, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 0, 0))
17+
>AEff : Symbol(AEff, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 4, 45))
18+
19+
f: () => Generator<Eff, AEff>
20+
>f : Symbol(f, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 4, 52))
21+
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
22+
>Eff : Symbol(Eff, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 4, 21))
23+
>AEff : Symbol(AEff, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 4, 45))
24+
25+
): Effect<AEff>;
26+
>Effect : Symbol(Effect, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 0, 0))
27+
>AEff : Symbol(AEff, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 4, 45))
28+
29+
interface Rpc<
30+
>Rpc : Symbol(Rpc, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 6, 16))
31+
32+
in out Tag extends string,
33+
>Tag : Symbol(Tag, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 8, 14))
34+
35+
out Payload = unknown,
36+
>Payload : Symbol(Payload, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 9, 28))
37+
38+
out Success = unknown
39+
>Success : Symbol(Success, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 10, 24))
40+
41+
> {
42+
readonly _tag: Tag;
43+
>_tag : Symbol(Rpc._tag, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 12, 3))
44+
>Tag : Symbol(Tag, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 8, 14))
45+
46+
readonly payloadSchema: Payload;
47+
>payloadSchema : Symbol(Rpc.payloadSchema, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 13, 21))
48+
>Payload : Symbol(Payload, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 9, 28))
49+
50+
readonly successSchema: Success;
51+
>successSchema : Symbol(Rpc.successSchema, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 14, 34))
52+
>Success : Symbol(Success, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 10, 24))
53+
}
54+
55+
interface RpcAny {
56+
>RpcAny : Symbol(RpcAny, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 16, 1))
57+
58+
readonly _tag: string;
59+
>_tag : Symbol(RpcAny._tag, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 18, 18))
60+
}
61+
62+
type Payload<R> = R extends Rpc<infer _Tag, infer _Payload, infer _Success>
63+
>Payload : Symbol(Payload, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 20, 1))
64+
>R : Symbol(R, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 22, 13))
65+
>R : Symbol(R, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 22, 13))
66+
>Rpc : Symbol(Rpc, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 6, 16))
67+
>_Tag : Symbol(_Tag, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 22, 37))
68+
>_Payload : Symbol(_Payload, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 22, 49))
69+
>_Success : Symbol(_Success, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 22, 65))
70+
71+
? _Payload
72+
>_Payload : Symbol(_Payload, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 22, 49))
73+
74+
: never;
75+
76+
type ResultFrom<R extends RpcAny> = R extends Rpc<
77+
>ResultFrom : Symbol(ResultFrom, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 24, 10))
78+
>R : Symbol(R, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 26, 16))
79+
>RpcAny : Symbol(RpcAny, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 16, 1))
80+
>R : Symbol(R, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 26, 16))
81+
>Rpc : Symbol(Rpc, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 6, 16))
82+
83+
infer _Tag,
84+
>_Tag : Symbol(_Tag, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 27, 7))
85+
86+
infer _Payload,
87+
>_Payload : Symbol(_Payload, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 28, 7))
88+
89+
infer _Success
90+
>_Success : Symbol(_Success, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 29, 7))
91+
92+
>
93+
? _Success
94+
>_Success : Symbol(_Success, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 29, 7))
95+
96+
: never;
97+
98+
type ToHandlerFn<Current extends RpcAny> = (
99+
>ToHandlerFn : Symbol(ToHandlerFn, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 32, 10))
100+
>Current : Symbol(Current, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 34, 17))
101+
>RpcAny : Symbol(RpcAny, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 16, 1))
102+
103+
payload: Payload<Current>
104+
>payload : Symbol(payload, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 34, 44))
105+
>Payload : Symbol(Payload, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 20, 1))
106+
>Current : Symbol(Current, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 34, 17))
107+
108+
) => ResultFrom<Current>;
109+
>ResultFrom : Symbol(ResultFrom, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 24, 10))
110+
>Current : Symbol(Current, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 34, 17))
111+
112+
type HandlersFrom<Rpc extends RpcAny> = {
113+
>HandlersFrom : Symbol(HandlersFrom, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 36, 25))
114+
>Rpc : Symbol(Rpc, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 38, 18))
115+
>RpcAny : Symbol(RpcAny, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 16, 1))
116+
117+
readonly [Current in Rpc as Current["_tag"]]: ToHandlerFn<Current>;
118+
>Current : Symbol(Current, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 39, 12))
119+
>Rpc : Symbol(Rpc, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 38, 18))
120+
>Current : Symbol(Current, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 39, 12))
121+
>ToHandlerFn : Symbol(ToHandlerFn, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 32, 10))
122+
>Current : Symbol(Current, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 39, 12))
123+
124+
};
125+
126+
interface RpcGroup<in out R extends RpcAny> {
127+
>RpcGroup : Symbol(RpcGroup, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 40, 2))
128+
>R : Symbol(R, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 42, 19))
129+
>RpcAny : Symbol(RpcAny, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 16, 1))
130+
131+
toLayer<Handlers extends HandlersFrom<R>>(build: Effect<Handlers>): unknown;
132+
>toLayer : Symbol(RpcGroup.toLayer, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 42, 45))
133+
>Handlers : Symbol(Handlers, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 43, 10))
134+
>HandlersFrom : Symbol(HandlersFrom, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 36, 25))
135+
>R : Symbol(R, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 42, 19))
136+
>build : Symbol(build, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 43, 44))
137+
>Effect : Symbol(Effect, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 0, 0))
138+
>Handlers : Symbol(Handlers, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 43, 10))
139+
}
140+
141+
declare const Rpcs: RpcGroup<Rpc<"Register", number, string>>;
142+
>Rpcs : Symbol(Rpcs, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 46, 13))
143+
>RpcGroup : Symbol(RpcGroup, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 40, 2))
144+
>Rpc : Symbol(Rpc, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 6, 16))
145+
146+
export const layerServerHandlers = Rpcs.toLayer(
147+
>layerServerHandlers : Symbol(layerServerHandlers, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 48, 12))
148+
>Rpcs.toLayer : Symbol(RpcGroup.toLayer, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 42, 45))
149+
>Rpcs : Symbol(Rpcs, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 46, 13))
150+
>toLayer : Symbol(RpcGroup.toLayer, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 42, 45))
151+
152+
gen(function* () {
153+
>gen : Symbol(gen, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 2, 1))
154+
155+
return {
156+
Register: (id) => String(id),
157+
>Register : Symbol(Register, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 50, 12))
158+
>id : Symbol(id, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 51, 17))
159+
>String : Symbol(String, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --) ... and 7 more)
160+
>id : Symbol(id, Decl(returnTypeInferenceContextualParameterTypesInGenerator1.ts, 51, 17))
161+
162+
};
163+
})
164+
);
165+
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
//// [tests/cases/compiler/returnTypeInferenceContextualParameterTypesInGenerator1.ts] ////
2+
3+
=== Performance Stats ===
4+
Type Count: 1,000
5+
Instantiation count: 2,500
6+
7+
=== returnTypeInferenceContextualParameterTypesInGenerator1.ts ===
8+
interface Effect<out A> {
9+
readonly _A: A;
10+
>_A : A
11+
> : ^
12+
}
13+
14+
declare function gen<Eff extends Effect<any>, AEff>(
15+
>gen : <Eff extends Effect<any>, AEff>(f: () => Generator<Eff, AEff>) => Effect<AEff>
16+
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^^^^
17+
18+
f: () => Generator<Eff, AEff>
19+
>f : () => Generator<Eff, AEff>
20+
> : ^^^^^^
21+
22+
): Effect<AEff>;
23+
24+
interface Rpc<
25+
in out Tag extends string,
26+
out Payload = unknown,
27+
out Success = unknown
28+
> {
29+
readonly _tag: Tag;
30+
>_tag : Tag
31+
> : ^^^
32+
33+
readonly payloadSchema: Payload;
34+
>payloadSchema : Payload
35+
> : ^^^^^^^
36+
37+
readonly successSchema: Success;
38+
>successSchema : Success
39+
> : ^^^^^^^
40+
}
41+
42+
interface RpcAny {
43+
readonly _tag: string;
44+
>_tag : string
45+
> : ^^^^^^
46+
}
47+
48+
type Payload<R> = R extends Rpc<infer _Tag, infer _Payload, infer _Success>
49+
>Payload : Payload<R>
50+
> : ^^^^^^^^^^
51+
52+
? _Payload
53+
: never;
54+
55+
type ResultFrom<R extends RpcAny> = R extends Rpc<
56+
>ResultFrom : ResultFrom<R>
57+
> : ^^^^^^^^^^^^^
58+
59+
infer _Tag,
60+
infer _Payload,
61+
infer _Success
62+
>
63+
? _Success
64+
: never;
65+
66+
type ToHandlerFn<Current extends RpcAny> = (
67+
>ToHandlerFn : ToHandlerFn<Current>
68+
> : ^^^^^^^^^^^^^^^^^^^^
69+
70+
payload: Payload<Current>
71+
>payload : Payload<Current>
72+
> : ^^^^^^^^^^^^^^^^
73+
74+
) => ResultFrom<Current>;
75+
76+
type HandlersFrom<Rpc extends RpcAny> = {
77+
>HandlersFrom : HandlersFrom<Rpc>
78+
> : ^^^^^^^^^^^^^^^^^
79+
80+
readonly [Current in Rpc as Current["_tag"]]: ToHandlerFn<Current>;
81+
};
82+
83+
interface RpcGroup<in out R extends RpcAny> {
84+
toLayer<Handlers extends HandlersFrom<R>>(build: Effect<Handlers>): unknown;
85+
>toLayer : <Handlers extends HandlersFrom<R>>(build: Effect<Handlers>) => unknown
86+
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
87+
>build : Effect<Handlers>
88+
> : ^^^^^^^^^^^^^^^^
89+
}
90+
91+
declare const Rpcs: RpcGroup<Rpc<"Register", number, string>>;
92+
>Rpcs : RpcGroup<Rpc<"Register", number, string>>
93+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
94+
95+
export const layerServerHandlers = Rpcs.toLayer(
96+
>layerServerHandlers : unknown
97+
> : ^^^^^^^
98+
>Rpcs.toLayer( gen(function* () { return { Register: (id) => String(id), }; })) : unknown
99+
> : ^^^^^^^
100+
>Rpcs.toLayer : <Handlers extends HandlersFrom<Rpc<"Register", number, string>>>(build: Effect<Handlers>) => unknown
101+
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
102+
>Rpcs : RpcGroup<Rpc<"Register", number, string>>
103+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
104+
>toLayer : <Handlers extends HandlersFrom<Rpc<"Register", number, string>>>(build: Effect<Handlers>) => unknown
105+
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
106+
107+
gen(function* () {
108+
>gen(function* () { return { Register: (id) => String(id), }; }) : Effect<{ Register: (id: number) => string; }>
109+
> : ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
110+
>gen : <Eff extends Effect<any>, AEff>(f: () => Generator<Eff, AEff>) => Effect<AEff>
111+
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^^^^
112+
>function* () { return { Register: (id) => String(id), }; } : () => Generator<never, { Register: (id: number) => string; }, any>
113+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
114+
115+
return {
116+
>{ Register: (id) => String(id), } : { Register: (id: number) => string; }
117+
> : ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
118+
119+
Register: (id) => String(id),
120+
>Register : (id: number) => string
121+
> : ^ ^^^^^^^^^^^^^^^^^^^
122+
>(id) => String(id) : (id: number) => string
123+
> : ^ ^^^^^^^^^^^^^^^^^^^
124+
>id : number
125+
> : ^^^^^^
126+
>String(id) : string
127+
> : ^^^^^^
128+
>String : StringConstructor
129+
> : ^^^^^^^^^^^^^^^^^
130+
>id : number
131+
> : ^^^^^^
132+
133+
};
134+
})
135+
);
136+

0 commit comments

Comments
 (0)