tristonj / eslint-plugin-prefer-arrow Goto Github PK
View Code? Open in Web Editor NEWESLint plugin to prefer arrow functions
License: MIT License
ESLint plugin to prefer arrow functions
License: MIT License
Take this example class:
class MyClass {
constructor() {
this.x = 0;
}
add(y) {
this.x += y;
}
}
I'd expect it to report an error, as the correct way would be:
class MyClass {
constructor() {
this.x = 0;
}
add = (y) => {
this.x += y;
};
}
Or have I misunderstood what this plugin does (there aren't examples in the docs)? This is the config I'm using:
"prefer-arrow/prefer-arrow-functions": [
"error",
{
"disallowPrototype": true,
"classPropertiesAllowed": false
}
]
Edit: Wow, I need to learn how to read. Looks like what I want is "classPropertiesAllowed" set to true
. I guess the wording confused me, I thought 'allowed' meant that it would ignore class methods. But it still doesn't work as expected, which is why I submitted #20.
This plugin is an excellent replacement for TSLint's only-arrow-functions
, as even recommended by the typescript-eslint
project.
However, only-arrow-functions
has the allow-declarations
option which allows for standalone declarations. In our codebase, we use non-arrow on every top-level function so using this plugin triggers hundreds of violations.
I would love to be able to use this rule to disallow the format above, without having to reformat our codebase. What do you think of an additional allowDeclarations
option?
In fact, we were/are using the recommended
preset of tslint-microsoft-contrib
, which uses this option, so it would make transitioning from TSLint to ESLint even easier :)
Hi,
I think the expression
var foo = function*() { return yield "bar"; };
should be an error with the default settings. However, it is not.
This is considered an arrow:
const myObject = {
get myVal() {
return something()
},
}
The fix will convert it to:
const myObject = {
get myVal: () => something(),
}
Which is not valid.
static methods are not class properties, so classPropertiesAllowed: true
shouldn't affect them
I don't think this is a very useful edge case, but I found this error running the plugin.
Returning undefined
resolves the problem.
.eslintrs.js
module.exports = {
'parserOptions': {
'ecmaVersion': 2018,
'sourceType': 'module',
},
'plugins': [
'prefer-arrow-functions',
],
'rules': {
'prefer-arrow-functions/prefer-arrow-functions': [
'error',
{
'classPropertiesAllowed': false,
'disallowPrototype': true,
'returnStyle': 'unchanged',
'singleReturnOnly': false,
},
],
},
};
file.js
function test() {
return;
}
Try to run:
yarn eslint --fix --plugin prefer-arrow-functions file.js
Error found:
TypeError: Cannot read properties of null (reading 'type')
Occurred while linting /home/pedr/repo/eslint-plugin-prefer-arrow/file.js:1
at getBodySource (/home/pedr/repo/eslint-plugin-prefer-arrow/node_modules/eslint-plugin-prefer-arrow-functions/dist/prefer-arrow-functions.js:57:36)
at getFunctionDescriptor (/home/pedr/repo/eslint-plugin-prefer-arrow/node_modules/eslint-plugin-prefer-arrow-functions/dist/prefer-arrow-functions.js:128:23)
at writeArrowConstant (/home/pedr/repo/eslint-plugin-prefer-arrow/node_modules/eslint-plugin-prefer-arrow-functions/dist/prefer-arrow-functions.js:121:24)
at Object.fix (/home/pedr/repo/eslint-plugin-prefer-arrow/node_modules/eslint-plugin-prefer-arrow-functions/dist/prefer-arrow-functions.js:243:60)
at normalizeFixes (/home/pedr/repo/eslint-plugin-prefer-arrow/node_modules/eslint/lib/linter/report-translator.js:178:28)
at /home/pedr/repo/eslint-plugin-prefer-arrow/node_modules/eslint/lib/linter/report-translator.js:343:49
at Object.report (/home/pedr/repo/eslint-plugin-prefer-arrow/node_modules/eslint/lib/linter/linter.js:905:41)
at FunctionDeclaration[parent.type!="ExportDefaultDeclaration"] (/home/pedr/repo/eslint-plugin-prefer-arrow/node_modules/eslint-plugin-prefer-arrow-functions/dist/prefer-arrow-functions.js:241:29)
at /home/pedr/repo/eslint-plugin-prefer-arrow/node_modules/eslint/lib/linter/safe-emitter.js:45:58
at Array.forEach (<anonymous>)
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
typescript-eslint lists this plugin as the TSLint replacement for only-arrow-functions
https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/ROADMAP.md
If that's the case then it's missing the allow-named-functions
option
https://palantir.github.io/tslint/rules/only-arrow-functions/
I'd also very much appreciate a rule details page that describe why we would want to use the rule etc.
Much like typescript-eslint do
https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-inferrable-types.md
Try adding the following to the invalid section of unit tests:
['function * generatorFunction() { return yield 1; }', 'function * generatorFunction() { return yield 1; }']
The test will fail because produced code will look like this:
const* test = () => yield 1;
The generator function can not be translated to the const
like definition. So all generator functions must be skipped.
This is my case:
const a = {
// no want to be detected
say() {}
}
Looking for helps!
trying to lint async functions in typescript that has a return type of Promise<void>
will cause the plugin to crash.
functions that returns something seems to be ok.
this is an example that repros the case
tester.run('lib/rules/prefer-arrow-functions', rule, {
parserOptions: {ecmaVersion: 6},
valid: [ ],
invalid: [
...[
// Support fixes with typescript typings
...[
[
`const good = {
async myFunc(a: number, b: number): Promise<number> {
return Promise.resolve(1);
}
}`,
`const good = {
async myFunc: (a: number, b: number): Promise<number> => Promise.resolve(1)
}`,
],
[
`const bad = {
async myFunc(a: number, b: number): Promise<void> {
return;
}
}`,
`const bad = {
async myFunc: (a: number, b: number): Promise<void> => {}
}`,
],
].map(test => [...test, null, { parser: require.resolve('@typescript-eslint/parser') }])
].map(inputOutput => Object.assign(
{
errors: ['Prefer using arrow functions over plain functions which only return a value'],
output: inputOutput[1],
...(inputOutput[3] || {}),
},
{
...singleReturnOnly(inputOutput[0], inputOutput[2]),
parserOptions: {
...singleReturnOnly(inputOutput[0], inputOutput[2]).parserOptions,
...((inputOutput[3] || {}).parserOptions || {})
},
}
)),
]
});
Thanks for adding the allowStandaloneDeclarations
option. However, this is still disallowed:
export function test() {
}
I think it should be allowed if allowStandaloneDeclarations
is set.
Trying to autofix an async function doesn't pick up the async modifier.
async function x(){
return 1
}
gets autofixed to
async const x = ()=> 1;
Is there a coherent reason to prefer arrow function expressions over function declarations in modules?
When exporting functions, there doesn't seem to be any benefits to enforce one to the other I believe.
Hi @TristonJ,
it seems like this repo and the accompanying NPM package aren't getting updated/maintained anymore - the last commit was 2 years ago, there are some open issues and PRs that I'd say are fairly important for the plugin functionality with no response.
Would you be willing to transfer the repo and NPM package to someone else? I'd be willing to take it over if you were. I understand there are some security considerations with transfering an existing package to "some rando on the internet", so I fully understand if you decline this request - I'll just fork the package and then it's on the users whether they trust the fork or not :)
Also wanted to note that I'm not trying to throw any shade here - this is open source work with no strings attached and no commitments and no obligation from your side, I understand that and I hope others do too. Thank you for your work on the plugin, it's much appreciated.
Mocha's documentation says:
Passing arrow functions (aka “lambdas”) to Mocha is discouraged. Lambdas lexically bind this and cannot access the Mocha context.
It would be nice if this plugin played nice with Mocha callbacks.
I opened an issue against the mocha
plugin as well: lo1tuma/eslint-plugin-mocha#275
There seems to be a strange bug here, this is on a typescript file. It fixes this:
Vue.use(Vuetify, {
theme: {
primary: '#008940',
accent: '#0279D7',
secondary: '#9F9F9F',
info: '#0279D7',
warning: '#B71C1C',
error: '#B71C1C',
success: '#4CAf50'
},
options: {
minifyTheme (css: string) {
return process.env.NODE_ENV === 'production'
? css.replace(/[\s|\r\n|\r|\n]/g, '')
: css
}
}
})
Vue.use(Vuetify, {
theme: {
primary: '#008940',
accent: '#0279D7',
secondary: '#9F9F9F',
info: '#0279D7',
warning: '#B71C1C',
error: '#B71C1C',
success: '#4CAf50'
},
options: {
minifyTheme :
}
})
The prefer-arrow-functions rule does not complain about foo
in this example:
const foo = function () {
const bar = function () {
console.log(this.toString());
};
return bar;
};
This rule is telling me I have to write my getters as arrow functions, which is impossible.
abstract class Foo {
abstract func(): void // no error
}
interface Bar {
func(): void // no error
}
type Baz = {
func(): void // no error
}
note: may not be necessary if typescript-eslint/typescript-eslint#5243 gets fixed
With the configuration:
'prefer-arrow/prefer-arrow-functions': ['warn', {
allowStandaloneDeclarations: true,
classPropertiesAllowed: true,
disallowPrototype: false,
singleReturnOnly: false,
}],
input:
export interface Example {
toString(): string;
}
is transformed into:
export interface Example {
toString: () => string;
}
Try adding the following to the invalid section of unit tests:
['function withLoop() { return () => { for (i = 0; i < 5; i++) {}}}', 'const withLoop = () => () => { for (i = 0; i < 5; i++) {}};']
The test will fail because produced code will look like this:
const withLoop = () => () => { for (i = 0; i < 5i++) {}};
The second semicolon is removed which leads to syntax error in the code.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.