Skip to content

Commit ce2ac17

Browse files
authored
Merge pull request microsoft#17771 from Microsoft/fixCircularContextualType
Fix circular contextual return type error
2 parents 93abebc + 57705fc commit ce2ac17

5 files changed

Lines changed: 74 additions & 1 deletion

File tree

src/compiler/checker.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6582,6 +6582,10 @@ namespace ts {
65826582
return signature.resolvedReturnType;
65836583
}
65846584

6585+
function isResolvingReturnTypeOfSignature(signature: Signature) {
6586+
return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, TypeSystemPropertyName.ResolvedReturnType) >= 0;
6587+
}
6588+
65856589
function getRestTypeOfSignature(signature: Signature): Type {
65866590
if (signature.hasRestParameter) {
65876591
const type = getTypeOfSymbol(lastOrUndefined(signature.parameters));
@@ -12955,7 +12959,7 @@ namespace ts {
1295512959
// Otherwise, if the containing function is contextually typed by a function type with exactly one call signature
1295612960
// and that call signature is non-generic, return statements are contextually typed by the return type of the signature
1295712961
const signature = getContextualSignatureForFunctionLikeDeclaration(<FunctionExpression>functionDecl);
12958-
if (signature) {
12962+
if (signature && !isResolvingReturnTypeOfSignature(signature)) {
1295912963
return getReturnTypeOfSignature(signature);
1296012964
}
1296112965

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//// [circularContextualReturnType.ts]
2+
// Repro from #17711
3+
4+
Object.freeze({
5+
foo() {
6+
return Object.freeze('a');
7+
},
8+
});
9+
10+
11+
//// [circularContextualReturnType.js]
12+
"use strict";
13+
// Repro from #17711
14+
Object.freeze({
15+
foo: function () {
16+
return Object.freeze('a');
17+
}
18+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
=== tests/cases/compiler/circularContextualReturnType.ts ===
2+
// Repro from #17711
3+
4+
Object.freeze({
5+
>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
6+
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
7+
>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
8+
9+
foo() {
10+
>foo : Symbol(foo, Decl(circularContextualReturnType.ts, 2, 15))
11+
12+
return Object.freeze('a');
13+
>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
14+
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
15+
>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
16+
17+
},
18+
});
19+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/compiler/circularContextualReturnType.ts ===
2+
// Repro from #17711
3+
4+
Object.freeze({
5+
>Object.freeze({ foo() { return Object.freeze('a'); },}) : Readonly<{ foo(): string; }>
6+
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
7+
>Object : ObjectConstructor
8+
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
9+
>{ foo() { return Object.freeze('a'); },} : { foo(): string; }
10+
11+
foo() {
12+
>foo : () => string
13+
14+
return Object.freeze('a');
15+
>Object.freeze('a') : string
16+
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
17+
>Object : ObjectConstructor
18+
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
19+
>'a' : "a"
20+
21+
},
22+
});
23+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @strict: true
2+
3+
// Repro from #17711
4+
5+
Object.freeze({
6+
foo() {
7+
return Object.freeze('a');
8+
},
9+
});

0 commit comments

Comments
 (0)