diff --git a/src/harness/unittests/extractConstants.ts b/src/harness/unittests/extractConstants.ts index 63a150856f5..314790537e3 100644 --- a/src/harness/unittests/extractConstants.ts +++ b/src/harness/unittests/extractConstants.ts @@ -214,6 +214,14 @@ const x = [#|2 + 1|]; /* About x */ const x = [#|2 + 1|]; `); + + testExtractConstant("extractConstant_ArrowFunction_Block", ` +const f = () => { + return [#|2 + 1|]; +};`); + + testExtractConstant("extractConstant_ArrowFunction_Expression", + `const f = () => [#|2 + 1|];`); }); function testExtractConstant(caption: string, text: string) { diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index d12e678dcec..92c36fd1c99 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -142,6 +142,7 @@ namespace ts.refactor.extractSymbol { export const CannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes"); export const CannotExtractToOtherFunctionLike = createMessage("Cannot extract method to a function-like scope that is not a function"); export const CannotExtractToJSClass = createMessage("Cannot extract constant to a class scope in JS"); + export const CannotExtractToExpressionArrowFunction = createMessage("Cannot extract constant to an arrow function without a block"); } enum RangeFacts { @@ -1299,6 +1300,10 @@ namespace ts.refactor.extractSymbol { if (isClassLike(scope) && isInJavaScriptFile(scope)) { constantErrors.push(createDiagnosticForNode(scope, Messages.CannotExtractToJSClass)); } + if (isArrowFunction(scope) && !isBlock(scope.body)) { + // TODO (https://github.com/Microsoft/TypeScript/issues/18924): allow this + constantErrors.push(createDiagnosticForNode(scope, Messages.CannotExtractToExpressionArrowFunction)); + } constantErrorsPerScope.push(constantErrors); } diff --git a/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.js b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.js new file mode 100644 index 00000000000..06dbf2b1751 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.js @@ -0,0 +1,18 @@ +// ==ORIGINAL== + +const f = () => { + return 2 + 1; +}; +// ==SCOPE::Extract to constant in enclosing scope== + +const f = () => { + const newLocal = 2 + 1; + + return /*RENAME*/newLocal; +}; +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +const f = () => { + return /*RENAME*/newLocal; +}; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.ts b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.ts new file mode 100644 index 00000000000..06dbf2b1751 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Block.ts @@ -0,0 +1,18 @@ +// ==ORIGINAL== + +const f = () => { + return 2 + 1; +}; +// ==SCOPE::Extract to constant in enclosing scope== + +const f = () => { + const newLocal = 2 + 1; + + return /*RENAME*/newLocal; +}; +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +const f = () => { + return /*RENAME*/newLocal; +}; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.js b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.js new file mode 100644 index 00000000000..d04cdcd3280 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.js @@ -0,0 +1,6 @@ +// ==ORIGINAL== +const f = () => 2 + 1; +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +const f = () => /*RENAME*/newLocal; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.ts b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.ts new file mode 100644 index 00000000000..d04cdcd3280 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ArrowFunction_Expression.ts @@ -0,0 +1,6 @@ +// ==ORIGINAL== +const f = () => 2 + 1; +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +const f = () => /*RENAME*/newLocal; \ No newline at end of file