diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2506e4632d893..2ccb41ae04218 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19114,8 +19114,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function hasContextSensitiveReturnExpression(node: FunctionLikeDeclaration) { - // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value. - return !node.typeParameters && !getEffectiveReturnTypeNode(node) && !!node.body && node.body.kind !== SyntaxKind.Block && isContextSensitive(node.body); + if (node.typeParameters || getEffectiveReturnTypeNode(node) || !node.body) { + return false; + } + if (node.body.kind !== SyntaxKind.Block) { + return isContextSensitive(node.body); + } + return !!forEachReturnStatement(node.body as Block, (statement) => !!statement.expression && isContextSensitive(statement.expression)); } function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration { diff --git a/tests/baselines/reference/inferPropertyWithContextSensitiveReturnStatement.symbols b/tests/baselines/reference/inferPropertyWithContextSensitiveReturnStatement.symbols new file mode 100644 index 0000000000000..1947ea8f7d120 --- /dev/null +++ b/tests/baselines/reference/inferPropertyWithContextSensitiveReturnStatement.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/inferPropertyWithContextSensitiveReturnStatement.ts === +// repro #50687 + +declare function repro(config: { +>repro : Symbol(repro, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 0, 0)) +>T : Symbol(T, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 2, 23)) +>config : Symbol(config, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 2, 26)) + + params: T; +>params : Symbol(params, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 2, 35)) +>T : Symbol(T, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 2, 23)) + + callback: () => (params: T) => number; +>callback : Symbol(callback, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 3, 12)) +>params : Symbol(params, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 4, 19)) +>T : Symbol(T, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 2, 23)) + +}): void; + +repro({ +>repro : Symbol(repro, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 0, 0)) + + params: 1, +>params : Symbol(params, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 7, 7)) + + callback: () => { return a => a + 1 }, +>callback : Symbol(callback, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 8, 12)) +>a : Symbol(a, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 9, 26)) +>a : Symbol(a, Decl(inferPropertyWithContextSensitiveReturnStatement.ts, 9, 26)) + +}); + diff --git a/tests/baselines/reference/inferPropertyWithContextSensitiveReturnStatement.types b/tests/baselines/reference/inferPropertyWithContextSensitiveReturnStatement.types new file mode 100644 index 0000000000000..24383ff66feaa --- /dev/null +++ b/tests/baselines/reference/inferPropertyWithContextSensitiveReturnStatement.types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/inferPropertyWithContextSensitiveReturnStatement.ts === +// repro #50687 + +declare function repro(config: { +>repro : (config: { params: T; callback: () => (params: T) => number; }) => void +>config : { params: T; callback: () => (params: T) => number; } + + params: T; +>params : T + + callback: () => (params: T) => number; +>callback : () => (params: T) => number +>params : T + +}): void; + +repro({ +>repro({ params: 1, callback: () => { return a => a + 1 },}) : void +>repro : (config: { params: T; callback: () => (params: T) => number; }) => void +>{ params: 1, callback: () => { return a => a + 1 },} : { params: number; callback: () => (a: number) => number; } + + params: 1, +>params : number +>1 : 1 + + callback: () => { return a => a + 1 }, +>callback : () => (a: number) => number +>() => { return a => a + 1 } : () => (a: number) => number +>a => a + 1 : (a: number) => number +>a : number +>a + 1 : number +>a : number +>1 : 1 + +}); + diff --git a/tests/cases/compiler/inferPropertyWithContextSensitiveReturnStatement.ts b/tests/cases/compiler/inferPropertyWithContextSensitiveReturnStatement.ts new file mode 100644 index 0000000000000..67bbed7bafcc3 --- /dev/null +++ b/tests/cases/compiler/inferPropertyWithContextSensitiveReturnStatement.ts @@ -0,0 +1,15 @@ +// @noEmit: true +// @strict: true + + +// repro #50687 + +declare function repro(config: { + params: T; + callback: () => (params: T) => number; +}): void; + +repro({ + params: 1, + callback: () => { return a => a + 1 }, +});