diff --git a/src/services/refactors/inferFunctionReturnType.ts b/src/services/refactors/inferFunctionReturnType.ts
index 4fad099cad029..535e25c330b4d 100644
--- a/src/services/refactors/inferFunctionReturnType.ts
+++ b/src/services/refactors/inferFunctionReturnType.ts
@@ -59,7 +59,9 @@ namespace ts.refactor.inferFunctionReturnType {
if (isInJSFile(context.file) || !refactorKindBeginsWith(inferReturnTypeAction.kind, context.kind)) return;
const token = getTokenAtPosition(context.file, context.startPosition);
- const declaration = findAncestor(token, isConvertibleDeclaration);
+ const declaration = findAncestor(token, n =>
+ isBlock(n) || n.parent && isArrowFunction(n.parent) && (n.kind === SyntaxKind.EqualsGreaterThanToken || n.parent.body === n) ? "quit" :
+ isConvertibleDeclaration(n)) as ConvertibleDeclaration | undefined;
if (!declaration || !declaration.body || declaration.type) {
return { error: getLocaleSpecificMessage(Diagnostics.Return_type_must_be_inferred_from_a_function) };
}
@@ -68,7 +70,7 @@ namespace ts.refactor.inferFunctionReturnType {
const returnType = tryGetReturnType(typeChecker, declaration);
if (!returnType) {
return { error: getLocaleSpecificMessage(Diagnostics.Could_not_determine_function_return_type) };
- };
+ }
const returnTypeNode = typeChecker.typeToTypeNode(returnType, declaration, NodeBuilderFlags.NoTruncation);
if (returnTypeNode) {
diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType16.ts b/tests/cases/fourslash/refactorInferFunctionReturnType16.ts
new file mode 100644
index 0000000000000..d8d281d546afe
--- /dev/null
+++ b/tests/cases/fourslash/refactorInferFunctionReturnType16.ts
@@ -0,0 +1,32 @@
+///
+
+////function /*a*//*b*/f1() {
+//// return { x: 1, y: 1 };
+////}
+////func/*c*//*d*/tion f2() {
+//// return { x: 1, y: 1 };
+////}
+////function f3(/*e*//*f*/) {
+//// return { x: 1, y: 1 };
+////}
+////function f4() {/*g*//*h*/
+//// return { x: 1, y: 1 };
+////}
+////function f5() {
+//// return { x: 1, y: 1 /*i*//*j*/};
+////}
+
+goTo.select("a", "b");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("c", "d");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("e", "f");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("g", "h");
+verify.not.refactorAvailable("Infer function return type");
+
+goTo.select("i", "j");
+verify.not.refactorAvailable("Infer function return type");
diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType17.ts b/tests/cases/fourslash/refactorInferFunctionReturnType17.ts
new file mode 100644
index 0000000000000..421b7aef2abad
--- /dev/null
+++ b/tests/cases/fourslash/refactorInferFunctionReturnType17.ts
@@ -0,0 +1,42 @@
+///
+
+////class F1 {
+//// /*a*//*b*/method() {
+//// return { x: 1, y: 1 };
+//// }
+////}
+////class F2 {
+//// met/*c*//*d*/hod(){
+//// return { x: 1, y: 1 };
+//// }
+////}
+////class F3 {
+//// method(/*e*//*f*/) {
+//// return { x: 1, y: 1 };
+//// }
+////}
+////class F4 {
+//// method() {
+//// return { x: 1, y: 1 /*g*//*h*/};
+//// }
+////}
+////class F5 {
+//// method() {
+//// return { x: 1, y: 1 /*i*//*j*/};
+//// }
+////}
+
+goTo.select("a", "b");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("c", "d");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("e", "f");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("g", "h");
+verify.not.refactorAvailable("Infer function return type");
+
+goTo.select("i", "j");
+verify.not.refactorAvailable("Infer function return type");
diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType18.ts b/tests/cases/fourslash/refactorInferFunctionReturnType18.ts
new file mode 100644
index 0000000000000..1006eeff534f2
--- /dev/null
+++ b/tests/cases/fourslash/refactorInferFunctionReturnType18.ts
@@ -0,0 +1,32 @@
+///
+
+////const f1 = /*a*//*b*/function () {
+//// return { x: 1, y: 1 };
+////}
+////const f2 = func/*c*//*d*/tion() {
+//// return { x: 1, y: 1 };
+////}
+////const f3 = function (/*e*//*f*/) {
+//// return { x: 1, y: 1 };
+////}
+////const f4 = function () {/*g*//*h*/
+//// return { x: 1, y: 1 };
+////}
+////const f5 = function () {
+//// return { x: 1, y: 1 /*i*//*j*/};
+////}
+
+goTo.select("a", "b");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("c", "d");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("e", "f");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("g", "h");
+verify.not.refactorAvailable("Infer function return type");
+
+goTo.select("i", "j");
+verify.not.refactorAvailable("Infer function return type");
diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType19.ts b/tests/cases/fourslash/refactorInferFunctionReturnType19.ts
new file mode 100644
index 0000000000000..8860c1ac7395e
--- /dev/null
+++ b/tests/cases/fourslash/refactorInferFunctionReturnType19.ts
@@ -0,0 +1,32 @@
+///
+
+////const f1 = /*a*//*b*/() =>{
+//// return { x: 1, y: 1 };
+////}
+////const f2 = (/*c*//*d*/) => {
+//// return { x: 1, y: 1 };
+////}
+////const f3 = () => /*e*//*f*/{
+//// return { x: 1, y: 1 };
+////}
+////const f4 = () => {/*g*//*h*/
+//// return { x: 1, y: 1 };
+////}
+////const f5 = () => {
+//// return { x: 1, y: 1/*i*//*j*/ };
+////}
+
+goTo.select("a", "b");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("c", "d");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("e", "f");
+verify.not.refactorAvailable("Infer function return type");
+
+goTo.select("g", "h");
+verify.not.refactorAvailable("Infer function return type");
+
+goTo.select("i", "j");
+verify.not.refactorAvailable("Infer function return type");
diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType20.ts b/tests/cases/fourslash/refactorInferFunctionReturnType20.ts
new file mode 100644
index 0000000000000..b5b29adc4ca5d
--- /dev/null
+++ b/tests/cases/fourslash/refactorInferFunctionReturnType20.ts
@@ -0,0 +1,20 @@
+///
+
+////function f1(/*a*//*b*/x, { y }) {
+//// return { x, y: 1 };
+////}
+////function f2(x, { /*c*//*d*/y }) {
+//// return { x, y: 1 };
+////}
+////function f3(x, /*e*//*f*/{ y }) {
+//// return { x, y: 1 };
+////}
+
+goTo.select("a", "b");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("c", "d");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("e", "f");
+verify.refactorAvailable("Infer function return type");
diff --git a/tests/cases/fourslash/refactorInferFunctionReturnType21.ts b/tests/cases/fourslash/refactorInferFunctionReturnType21.ts
new file mode 100644
index 0000000000000..544be7bc5c864
--- /dev/null
+++ b/tests/cases/fourslash/refactorInferFunctionReturnType21.ts
@@ -0,0 +1,18 @@
+///
+
+////const f1 = /*a*//*b*/(x: number) => x;
+////const f2 = (x: number) /*c*//*d*/=> x;
+////const f3 = (x: number) => /*e*//*f*/x
+////const f4= (x: number) => x/*g*//*h*/
+
+goTo.select("a", "b");
+verify.refactorAvailable("Infer function return type");
+
+goTo.select("c", "d");
+verify.not.refactorAvailable("Infer function return type");
+
+goTo.select("e", "f");
+verify.not.refactorAvailable("Infer function return type");
+
+goTo.select("g", "h");
+verify.not.refactorAvailable("Infer function return type");
diff --git a/tests/cases/fourslash/refactorKind_rewriteFunction.ts b/tests/cases/fourslash/refactorKind_rewriteFunction.ts
index 56fe42cd9a449..b6946a99fa31a 100644
--- a/tests/cases/fourslash/refactorKind_rewriteFunction.ts
+++ b/tests/cases/fourslash/refactorKind_rewriteFunction.ts
@@ -1,10 +1,9 @@
///
-//// const arrow = () /*a*/=>/*b*/ 1;
+//// const arrow = /*a*//*b*/() => 1;
goTo.select("a", "b");
-verify.refactorKindAvailable("refactor.rewrite",
-[
+verify.refactorKindAvailable("refactor.rewrite", [
"refactor.rewrite.arrow.braces.add",
"refactor.rewrite.function.named",
"refactor.rewrite.function.anonymous",