Skip to content

Commit b272a2b

Browse files
committed
feat: allow methods on objects
Closes #15
1 parent 0021931 commit b272a2b

File tree

5 files changed

+56
-0
lines changed

5 files changed

+56
-0
lines changed

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Add the plugin to the `plugins` section and the rule to the `rules` section in y
2121
{
2222
"allowedNames": [],
2323
"allowNamedFunctions": false,
24+
"allowObjectProperties": false,
2425
"classPropertiesAllowed": false,
2526
"disallowPrototype": false,
2627
"returnStyle": "unchanged",
@@ -41,6 +42,16 @@ An optional array of function names to ignore. When set, the rule won't report n
4142

4243
If set to true, the rule won't report named functions such as `function foo() {}`. Anonymous function such as `const foo = function() {}` will still be reported.
4344

45+
### `allowObjectProperties`
46+
47+
If set to true, the rule won't report named methods such as
48+
49+
```js
50+
const myObj = {
51+
hello() {}
52+
}
53+
```
54+
4455
### `classPropertiesAllowed`
4556

4657
When `true`, functions defined as [class instance fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Field_declarations) will be converted to arrow functions when doing so would not alter or break their behaviour.

src/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export interface Scope {
1919
export interface ActualOptions {
2020
allowedNames: string[];
2121
allowNamedFunctions: boolean;
22+
allowObjectProperties: boolean;
2223
classPropertiesAllowed: boolean;
2324
disallowPrototype: boolean;
2425
returnStyle: 'explicit' | 'implicit' | 'unchanged';
@@ -28,6 +29,7 @@ export interface ActualOptions {
2829
export const DEFAULT_OPTIONS: ActualOptions = {
2930
allowedNames: [],
3031
allowNamedFunctions: false,
32+
allowObjectProperties: false,
3133
classPropertiesAllowed: false,
3234
disallowPrototype: false,
3335
returnStyle: 'unchanged',

src/guard.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,15 @@ export class Guard {
163163
return this.isNamedFunction(fn) && this.options.allowedNames.includes(fn.id.name);
164164
}
165165

166+
isObjectProperty(fn: AnyFunction): boolean {
167+
return this.sourceCode
168+
.getAncestors(fn)
169+
.reverse()
170+
.some((ancestor) => {
171+
return ancestor.type === AST_NODE_TYPES.Property;
172+
});
173+
}
174+
166175
isSafeTransformation(fn: TSESTree.Node): fn is AnyFunction {
167176
const isSafe =
168177
this.isAnyFunction(fn) &&
@@ -178,6 +187,7 @@ export class Guard {
178187
if (this.options.allowNamedFunctions && this.isNamedFunction(fn)) return false;
179188
if (!this.options.disallowPrototype && this.isPrototypeAssignment(fn)) return false;
180189
if (this.options.singleReturnOnly && !this.returnsImmediately(fn)) return false;
190+
if (this.isObjectProperty(fn) && this.options.allowObjectProperties) return false;
181191
if (this.hasNameAndIsExportedAsDefaultExport(fn)) return false;
182192
return true;
183193
}

src/rule.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ export const preferArrowFunctions = createRule<Options, MessageId>({
3030
default: DEFAULT_OPTIONS.allowNamedFunctions,
3131
type: 'boolean',
3232
},
33+
allowObjectProperties: {
34+
default: DEFAULT_OPTIONS.allowObjectProperties,
35+
type: 'boolean',
36+
},
3337
classPropertiesAllowed: {
3438
default: DEFAULT_OPTIONS.classPropertiesAllowed,
3539
type: 'boolean',

test/rule.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,35 @@ describe('when classPropertiesAllowed is true', () => {
194194
});
195195
});
196196

197+
describe('allowObjectProperties', () => {
198+
describe('when property can be converted to an arrow function', () => {
199+
describe('leaves the method as is when allowObjectProperties is true', () => {
200+
ruleTester.run('prefer-arrow-functions', rule, {
201+
valid: [
202+
{
203+
code: 'const foo = { render(a, b) { console.log(3); } }',
204+
},
205+
{
206+
code: 'export default { data(){ return 4 } }',
207+
},
208+
].map(withOptions({ allowObjectProperties: true })),
209+
invalid: [
210+
{
211+
code: 'const foo = { render(a, b) { return a + b; } }',
212+
output: 'const foo = { render: (a, b) => a + b }',
213+
},
214+
{
215+
code: 'export default { data(){ return 4 } }',
216+
output: 'export default { data: () => 4 }',
217+
},
218+
]
219+
.map(withOptions({ allowObjectProperties: false }))
220+
.map(withErrors(['USE_ARROW_WHEN_FUNCTION'])),
221+
});
222+
});
223+
});
224+
});
225+
197226
describe('when singleReturnOnly is true', () => {
198227
describe('when function should be an arrow function', () => {
199228
describe('when function does not contain only a return statement', () => {

0 commit comments

Comments
 (0)