Skip to content

Commit 0a5da2f

Browse files
committed
Make function properties context-sensitive based on their return statements
1 parent 57c7aa7 commit 0a5da2f

4 files changed

+90
-2
lines changed

src/compiler/checker.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -17588,8 +17588,13 @@ namespace ts {
1758817588
}
1758917589

1759017590
function hasContextSensitiveReturnExpression(node: FunctionLikeDeclaration) {
17591-
// TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value.
17592-
return !node.typeParameters && !getEffectiveReturnTypeNode(node) && !!node.body && node.body.kind !== SyntaxKind.Block && isContextSensitive(node.body);
17591+
if (node.typeParameters || getEffectiveReturnTypeNode(node) || !node.body) {
17592+
return false;
17593+
}
17594+
if (node.body.kind !== SyntaxKind.Block) {
17595+
return isContextSensitive(node.body);
17596+
}
17597+
return !!forEachReturnStatement(node.body as Block, (statement) => !!statement.expression && isContextSensitive(statement.expression));
1759317598
}
1759417599

1759517600
function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/compiler/inferPropertyWithContextSensitiveReturnStatement.ts ===
2+
// repro #50687
3+
4+
declare function repro<T>(config: {
5+
>repro : Symbol(repro, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 0, 0))
6+
>T : Symbol(T, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 2, 23))
7+
>config : Symbol(config, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 2, 26))
8+
9+
params: T;
10+
>params : Symbol(params, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 2, 35))
11+
>T : Symbol(T, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 2, 23))
12+
13+
callback: () => (params: T) => number;
14+
>callback : Symbol(callback, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 3, 12))
15+
>params : Symbol(params, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 4, 19))
16+
>T : Symbol(T, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 2, 23))
17+
18+
}): void;
19+
20+
repro({
21+
>repro : Symbol(repro, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 0, 0))
22+
23+
params: 1,
24+
>params : Symbol(params, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 7, 7))
25+
26+
callback: () => { return a => a + 1 },
27+
>callback : Symbol(callback, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 8, 12))
28+
>a : Symbol(a, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 9, 26))
29+
>a : Symbol(a, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 9, 26))
30+
31+
});
32+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/compiler/inferPropertyWithContextSensitiveReturnStatement.ts ===
2+
// repro #50687
3+
4+
declare function repro<T>(config: {
5+
>repro : <T>(config: { params: T; callback: () => (params: T) => number; }) => void
6+
>config : { params: T; callback: () => (params: T) => number; }
7+
8+
params: T;
9+
>params : T
10+
11+
callback: () => (params: T) => number;
12+
>callback : () => (params: T) => number
13+
>params : T
14+
15+
}): void;
16+
17+
repro({
18+
>repro({ params: 1, callback: () => { return a => a + 1 },}) : void
19+
>repro : <T>(config: { params: T; callback: () => (params: T) => number; }) => void
20+
>{ params: 1, callback: () => { return a => a + 1 },} : { params: number; callback: () => (a: number) => number; }
21+
22+
params: 1,
23+
>params : number
24+
>1 : 1
25+
26+
callback: () => { return a => a + 1 },
27+
>callback : () => (a: number) => number
28+
>() => { return a => a + 1 } : () => (a: number) => number
29+
>a => a + 1 : (a: number) => number
30+
>a : number
31+
>a + 1 : number
32+
>a : number
33+
>1 : 1
34+
35+
});
36+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @noEmit: true
2+
// @strict: true
3+
4+
5+
// repro #50687
6+
7+
declare function repro<T>(config: {
8+
params: T;
9+
callback: () => (params: T) => number;
10+
}): void;
11+
12+
repro({
13+
params: 1,
14+
callback: () => { return a => a + 1 },
15+
});

0 commit comments

Comments
 (0)