Skip to content

Commit 2a5f613

Browse files
committed
feat: support computed property methods
Closes #60
1 parent a0acd2a commit 2a5f613

File tree

2 files changed

+128
-3
lines changed

2 files changed

+128
-3
lines changed

src/rule.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,26 @@ export const preferArrowFunctions = createRule<Options, MessageId>({
8585
});
8686
}
8787
},
88-
':matches(ClassProperty, MethodDefinition, Property)[key.name][value.type="FunctionExpression"][kind!=/^(get|set|constructor)$/]':
88+
':matches(ClassProperty, MethodDefinition, Property)[value.type="FunctionExpression"][kind!=/^(get|set|constructor)$/]':
8989
(node: TSESTree.MethodDefinition | TSESTree.Property) => {
9090
const fn = node.value;
9191
if (guard.isSafeTransformation(fn) && (!guard.isWithinClassBody(fn) || options.classPropertiesAllowed)) {
92-
const name = 'name' in node.key ? node.key.name : '';
93-
const propName = node.key.type === AST_NODE_TYPES.PrivateIdentifier ? `#${name}` : name;
92+
let propName: string;
93+
94+
if (node.key.type === AST_NODE_TYPES.PrivateIdentifier) {
95+
const name = 'name' in node.key ? node.key.name : '';
96+
propName = `#${name}`;
97+
} else if (node.computed) {
98+
// For computed properties like [foo], [Symbol.iterator], etc.
99+
propName = `[${sourceCode.getText(node.key)}]`;
100+
} else if ('name' in node.key) {
101+
// For simple property names
102+
propName = node.key.name;
103+
} else {
104+
// Fallback to source text for other cases
105+
propName = sourceCode.getText(node.key);
106+
}
107+
94108
const staticModifier = 'static' in node && node.static ? 'static ' : '';
95109
ctx.report({
96110
fix: (fixer) =>

test/rule.spec.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,3 +513,114 @@ describe('when file is TSX', () => {
513513
});
514514
});
515515
});
516+
517+
describe('issue #60 - computed property keys should be preserved', () => {
518+
describe('when computed property methods should NOT be transformed', () => {
519+
ruleTester.run('prefer-arrow-functions', rule, {
520+
valid: [
521+
{
522+
code: `const obj = {
523+
[Symbol.iterator]() {
524+
return this;
525+
},
526+
};`,
527+
},
528+
{
529+
code: `const dynamicKey = 'method';
530+
const obj = {
531+
[dynamicKey]() {
532+
console.log(this.value);
533+
},
534+
};`,
535+
},
536+
{
537+
code: `const obj = {
538+
['computed-key']() {
539+
return arguments[0];
540+
},
541+
};`,
542+
},
543+
{
544+
code: `const prefix = 'handle';
545+
const suffix = 'Click';
546+
const obj = {
547+
[prefix + suffix]() {
548+
super.onClick();
549+
},
550+
};`,
551+
},
552+
],
553+
invalid: [],
554+
});
555+
});
556+
557+
describe('when computed property methods can be safely transformed', () => {
558+
ruleTester.run('prefer-arrow-functions', rule, {
559+
valid: [],
560+
invalid: [
561+
{
562+
code: `const foo = 'bar';
563+
export default {
564+
[foo]() {
565+
console.log('output');
566+
},
567+
};`,
568+
output: `const foo = 'bar';
569+
export default {
570+
[foo]: () => {
571+
console.log('output');
572+
},
573+
};`,
574+
},
575+
{
576+
code: `const methodName = 'getData';
577+
const obj = {
578+
[methodName]() {
579+
return 42;
580+
},
581+
};`,
582+
output: `const methodName = 'getData';
583+
const obj = {
584+
[methodName]: () => 42,
585+
};`,
586+
},
587+
{
588+
code: `const obj = {
589+
['computed-key']() {
590+
return 'value';
591+
},
592+
};`,
593+
output: `const obj = {
594+
['computed-key']: () => 'value',
595+
};`,
596+
},
597+
{
598+
code: `const obj = {
599+
[Symbol.iterator]() {
600+
return 'iterator';
601+
},
602+
};`,
603+
output: `const obj = {
604+
[Symbol.iterator]: () => 'iterator',
605+
};`,
606+
},
607+
{
608+
code: `const prefix = 'handle';
609+
const suffix = 'Click';
610+
const obj = {
611+
[prefix + suffix]() {
612+
console.log('clicked');
613+
},
614+
};`,
615+
output: `const prefix = 'handle';
616+
const suffix = 'Click';
617+
const obj = {
618+
[prefix + suffix]: () => {
619+
console.log('clicked');
620+
},
621+
};`,
622+
},
623+
].map(withErrors(['USE_ARROW_WHEN_FUNCTION'])),
624+
});
625+
});
626+
});

0 commit comments

Comments
 (0)