Skip to content

Commit 8d1fa44

Browse files
Andaristsandersn
andauthored
Defer processing of nested generic calls that return constructor types (#54813)
Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
1 parent eb2046d commit 8d1fa44

File tree

4 files changed

+170
-3
lines changed

4 files changed

+170
-3
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34776,7 +34776,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3477634776
// use the resolvingSignature singleton to indicate that we deferred processing. This result will be
3477734777
// propagated out and eventually turned into silentNeverType (a type that is assignable to anything and
3477834778
// from which we never make inferences).
34779-
if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
34779+
if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunctionOrConstructor)) {
3478034780
skippedGenericFunction(node, checkMode);
3478134781
return resolvingSignature;
3478234782
}
@@ -34789,8 +34789,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3478934789
return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags);
3479034790
}
3479134791

34792-
function isGenericFunctionReturningFunction(signature: Signature) {
34793-
return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature)));
34792+
function isGenericFunctionReturningFunctionOrConstructor(signature: Signature) {
34793+
if (!signature.typeParameters) {
34794+
return false;
34795+
}
34796+
const returnType = getReturnTypeOfSignature(signature);
34797+
return isFunctionType(returnType) || isConstructorType(returnType);
3479434798
}
3479534799

3479634800
/**
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//// [tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts] ////
2+
3+
=== inferenceGenericNestedCallReturningConstructor.ts ===
4+
interface Action<TContext> {
5+
>Action : Symbol(Action, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 0))
6+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 17))
7+
8+
new (ctx: TContext): void;
9+
>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 1, 7))
10+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 17))
11+
}
12+
13+
declare class AssignAction<TContext> {
14+
>AssignAction : Symbol(AssignAction, Decl(inferenceGenericNestedCallReturningConstructor.ts, 2, 1))
15+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 4, 27))
16+
17+
constructor(ctx: TContext);
18+
>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 5, 14))
19+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 4, 27))
20+
}
21+
22+
declare function assign<TContext>(
23+
>assign : Symbol(assign, Decl(inferenceGenericNestedCallReturningConstructor.ts, 6, 1))
24+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24))
25+
26+
assigner: (ctx: TContext) => void
27+
>assigner : Symbol(assigner, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 34))
28+
>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 9, 13))
29+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24))
30+
31+
): {
32+
new (ctx: TContext): AssignAction<TContext>;
33+
>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 11, 7))
34+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24))
35+
>AssignAction : Symbol(AssignAction, Decl(inferenceGenericNestedCallReturningConstructor.ts, 2, 1))
36+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 8, 24))
37+
}
38+
39+
declare function createMachine<TContext>(config: {
40+
>createMachine : Symbol(createMachine, Decl(inferenceGenericNestedCallReturningConstructor.ts, 12, 1))
41+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 31))
42+
>config : Symbol(config, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 41))
43+
44+
context: TContext;
45+
>context : Symbol(context, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 50))
46+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 31))
47+
48+
entry: Action<TContext>;
49+
>entry : Symbol(entry, Decl(inferenceGenericNestedCallReturningConstructor.ts, 15, 20))
50+
>Action : Symbol(Action, Decl(inferenceGenericNestedCallReturningConstructor.ts, 0, 0))
51+
>TContext : Symbol(TContext, Decl(inferenceGenericNestedCallReturningConstructor.ts, 14, 31))
52+
53+
}): void;
54+
55+
createMachine({
56+
>createMachine : Symbol(createMachine, Decl(inferenceGenericNestedCallReturningConstructor.ts, 12, 1))
57+
58+
context: { count: 0 },
59+
>context : Symbol(context, Decl(inferenceGenericNestedCallReturningConstructor.ts, 19, 15))
60+
>count : Symbol(count, Decl(inferenceGenericNestedCallReturningConstructor.ts, 20, 12))
61+
62+
entry: assign((ctx) => {
63+
>entry : Symbol(entry, Decl(inferenceGenericNestedCallReturningConstructor.ts, 20, 24))
64+
>assign : Symbol(assign, Decl(inferenceGenericNestedCallReturningConstructor.ts, 6, 1))
65+
>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 21, 17))
66+
67+
ctx // { count: number }
68+
>ctx : Symbol(ctx, Decl(inferenceGenericNestedCallReturningConstructor.ts, 21, 17))
69+
70+
}),
71+
});
72+
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//// [tests/cases/compiler/inferenceGenericNestedCallReturningConstructor.ts] ////
2+
3+
=== inferenceGenericNestedCallReturningConstructor.ts ===
4+
interface Action<TContext> {
5+
new (ctx: TContext): void;
6+
>ctx : TContext
7+
}
8+
9+
declare class AssignAction<TContext> {
10+
>AssignAction : AssignAction<TContext>
11+
12+
constructor(ctx: TContext);
13+
>ctx : TContext
14+
}
15+
16+
declare function assign<TContext>(
17+
>assign : <TContext>(assigner: (ctx: TContext) => void) => new (ctx: TContext) => AssignAction<TContext>
18+
19+
assigner: (ctx: TContext) => void
20+
>assigner : (ctx: TContext) => void
21+
>ctx : TContext
22+
23+
): {
24+
new (ctx: TContext): AssignAction<TContext>;
25+
>ctx : TContext
26+
}
27+
28+
declare function createMachine<TContext>(config: {
29+
>createMachine : <TContext>(config: { context: TContext; entry: Action<TContext>;}) => void
30+
>config : { context: TContext; entry: Action<TContext>; }
31+
32+
context: TContext;
33+
>context : TContext
34+
35+
entry: Action<TContext>;
36+
>entry : Action<TContext>
37+
38+
}): void;
39+
40+
createMachine({
41+
>createMachine({ context: { count: 0 }, entry: assign((ctx) => { ctx // { count: number } }),}) : void
42+
>createMachine : <TContext>(config: { context: TContext; entry: Action<TContext>; }) => void
43+
>{ context: { count: 0 }, entry: assign((ctx) => { ctx // { count: number } }),} : { context: { count: number; }; entry: new (ctx: { count: number; }) => AssignAction<{ count: number; }>; }
44+
45+
context: { count: 0 },
46+
>context : { count: number; }
47+
>{ count: 0 } : { count: number; }
48+
>count : number
49+
>0 : 0
50+
51+
entry: assign((ctx) => {
52+
>entry : new (ctx: { count: number; }) => AssignAction<{ count: number; }>
53+
>assign((ctx) => { ctx // { count: number } }) : new (ctx: { count: number; }) => AssignAction<{ count: number; }>
54+
>assign : <TContext>(assigner: (ctx: TContext) => void) => new (ctx: TContext) => AssignAction<TContext>
55+
>(ctx) => { ctx // { count: number } } : (ctx: { count: number; }) => void
56+
>ctx : { count: number; }
57+
58+
ctx // { count: number }
59+
>ctx : { count: number; }
60+
61+
}),
62+
});
63+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
interface Action<TContext> {
5+
new (ctx: TContext): void;
6+
}
7+
8+
declare class AssignAction<TContext> {
9+
constructor(ctx: TContext);
10+
}
11+
12+
declare function assign<TContext>(
13+
assigner: (ctx: TContext) => void
14+
): {
15+
new (ctx: TContext): AssignAction<TContext>;
16+
}
17+
18+
declare function createMachine<TContext>(config: {
19+
context: TContext;
20+
entry: Action<TContext>;
21+
}): void;
22+
23+
createMachine({
24+
context: { count: 0 },
25+
entry: assign((ctx) => {
26+
ctx // { count: number }
27+
}),
28+
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy