Skip to content

Commit

Permalink
Make function properties context-sensitive based on their return stat…
Browse files Browse the repository at this point in the history
…ements (#50903)
  • Loading branch information
Andarist authored Mar 20, 2023
1 parent 4fcb8b8 commit acfb0b5
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
=== tests/cases/compiler/inferPropertyWithContextSensitiveReturnStatement.ts ===
// repro #50687

declare function repro<T>(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))

});

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
=== tests/cases/compiler/inferPropertyWithContextSensitiveReturnStatement.ts ===
// repro #50687

declare function repro<T>(config: {
>repro : <T>(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 : <T>(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

});

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// @noEmit: true
// @strict: true


// repro #50687

declare function repro<T>(config: {
params: T;
callback: () => (params: T) => number;
}): void;

repro({
params: 1,
callback: () => { return a => a + 1 },
});

0 comments on commit acfb0b5

Please sign in to comment.