Skip to content

Commit 8a8b22e

Browse files
committed
Defer processing of nested generic calls that return constructor types
1 parent 6696ecd commit 8a8b22e

4 files changed

+141
-3
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33667,7 +33667,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3366733667
// use the resolvingSignature singleton to indicate that we deferred processing. This result will be
3366833668
// propagated out and eventually turned into silentNeverType (a type that is assignable to anything and
3366933669
// from which we never make inferences).
33670-
if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
33670+
if (checkMode & CheckMode.SkipGenericFunctions && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunctionOrConstructor)) {
3367133671
skippedGenericFunction(node, checkMode);
3367233672
return resolvingSignature;
3367333673
}
@@ -33680,8 +33680,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3368033680
return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags);
3368133681
}
3368233682

33683-
function isGenericFunctionReturningFunction(signature: Signature) {
33684-
return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature)));
33683+
function isGenericFunctionReturningFunctionOrConstructor(signature: Signature) {
33684+
if (!signature.typeParameters) {
33685+
return false;
33686+
}
33687+
const returnType = getReturnTypeOfSignature(signature);
33688+
return isFunctionType(returnType) || isConstructorType(returnType);
3368533689
}
3368633690

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

0 commit comments

Comments
 (0)