30

I prefer this:

const foo = x => x + 1;

to this:

function foo(x) {
  return x + 1;
}

Is there an ESLint rule to enforce this?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
sdgfsdh
  • 33,689
  • 26
  • 132
  • 245
  • 11
    Since they're not freely interchangeable, you probably *shouldn't*. – deceze Oct 05 '18 at 15:52
  • 5
    It's worth noting that those two are not necessarily equivalent, and enforcing one over the other could cause issues: https://stackoverflow.com/a/34361380/1650337 – DBS Oct 05 '18 at 15:53
  • @DBS I am not using features likely to cause issues (such as `this`) either – sdgfsdh Oct 05 '18 at 16:21

4 Answers4

16

Anser based on @JohannesEwald comment and @KevinAmiranoff answer.

I'm using the following rules:

https://www.npmjs.com/package/eslint-plugin-prefer-arrow

https://eslint.org/docs/rules/prefer-arrow-callback

https://eslint.org/docs/rules/func-style

npm install -D eslint-plugin-prefer-arrow

.eslintrc or package.json with eslintConfig:

"plugins": [
  "prefer-arrow"
],
"rules": {
  "prefer-arrow/prefer-arrow-functions": [
    "error",
    {
      "disallowPrototype": true,
      "singleReturnOnly": false,
      "classPropertiesAllowed": false
    }
  ],
  "prefer-arrow-callback": [
    "error",
    { "allowNamedFunctions": true }
  ],
  "func-style": [
    "error",
    "expression",
    { "allowArrowFunctions": true }
  ]
}

I think this works really well. If you need to disable the rules for a specific line I do it like this:

// eslint-disable-next-line func-style, prefer-arrow/prefer-arrow-functions
Ogglas
  • 62,132
  • 37
  • 328
  • 418
15

You can use this ESLint prefer-arrow-callback rule which would flag with error/warning anywhere you could use an arrow function instead of a function expression

Kevin Amiranoff
  • 13,440
  • 11
  • 59
  • 90
  • 5
    But only in callbacks? – sdgfsdh Oct 05 '18 at 16:21
  • 1
    oh yeah true. I guess it is not exactly what you want. – Kevin Amiranoff Oct 05 '18 at 16:24
  • 11
    I use the eslint-plugin-prefer-arrow package (https://www.npmjs.com/package/eslint-plugin-prefer-arrow) in conjunction with `"func-style": ["error", "expression"]` and it works quite well. – Johannes Ewald Feb 24 '19 at 20:48
  • @JohannesEwald I just started using both the plugin and the style rule, and I noticed that I'm getting lot of duplicated errors, that is, lines which are marked as an error by both the plugin and the style rule. – Paul Razvan Berg Oct 22 '22 at 19:33
8

You can use ESLint's built-in no-restricted-syntax rule to disallow the FunctionExpression and FunctionDeclaration AST nodes:

{
  "rules": {
    "no-restricted-syntax": [
      "error",
      "FunctionExpression",
      "FunctionDeclaration"
    ]
  }
}

This doesn't explicitly "prefer" arrow functions, but if you disallow all ArrowFunctionExpression alternatives, then you effectively enforce arrow functions only.

With the above rule, these fail:

// VariableDeclaration containing a FunctionExpression
const f1 = function () {}

// FunctionDeclaration
function f2() {}

class C {
  // MethodDefinition containing a FunctionExpression
  m() {}
}

These pass:

// VariableDeclaration containing an ArrowFunctionExpression
const f = () => {}

class C {
  // PropertyDefinition containing an ArrowFunctionExpression
  m = () => {}
}

If you want to allow FunctionExpression and FunctionDeclaration nodes when they reference this or when they are generator functions (there's no such thing as an arrow generator function currently), then you can use esquery syntax to specifically disallow those nodes when they don't have a ThisExpression node as a descendant and they aren't generator functions:

{
  "rules": {
    "no-restricted-syntax": [
      "error",
      "FunctionExpression[generator=false]:not(:has(ThisExpression))",
      "FunctionDeclaration[generator=false]:not(:has(ThisExpression))"
    ]
  }
}

With the above rule, these fail:

// VariableDeclaration containing a FunctionExpression
const f1 = function () {}

// FunctionDeclaration
function f2() {}

class C {
  // MethodDefinition containing a FunctionExpression
  m() {}
}

These pass:

// VariableDeclaration containing a FunctionExpression containing a ThisExpression
const f1 = function () {
  this.x = 42
}

// VariableDeclaration containing a FunctionExpression[generator=true]
const f2 = function* () {}

// FunctionDeclaration containing a ThisExpression
function f3() {
  this.x = 42
}

// FunctionDeclaration[generator=true]
function* f4() {}

// VariableDeclaration containing an ArrowFunctionExpression
const f5 = () => {}

class C {
  // MethodDefinition containing a FunctionExpression containing a ThisExpression
  m1() {
    this.x = 42
  }

  // MethodDefinition containing a FunctionExpression[generator=true]
  *m2() {}
  
  // PropertyDefinition containing an ArrowFunctionExpression
  m3 = () => {}
}

Unfortunately, the function f in the following example is also allowed even though it could be rewritten as an arrow function:

function f() {
  function g() {
    this.x = 42
  }

  return g
}

I wasn't able to come up with an esquery selector that includes functions like f while excluding functions like g.

Tomer Aberbach
  • 536
  • 3
  • 11
0

allow only arrow function guide

you can refer this.

in the .eslintrc.json file enter these in the rules section:

"react/function-component-definition": [2, { "namedComponents": "arrow-function" }]

Gokulaselvan
  • 118
  • 7