Skip to content

Commit

Permalink
feat(eslint-plugin): [consistent-generic-ctors] check class field dec…
Browse files Browse the repository at this point in the history
…laration (#5288)

* feat(eslint-plugin): [consistent-generic-ctors] report class field declaration

* add a test

Co-authored-by: Josh Goldberg <me@joshuakgoldberg.com>
  • Loading branch information
Josh-Cena and JoshuaKGoldberg committed Jul 22, 2022
1 parent 29b7c02 commit 48f996e
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 5 deletions.
@@ -1,4 +1,4 @@
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils';
import { createRule } from '../util';

type MessageIds = 'preferTypeAnnotation' | 'preferConstructor';
Expand Down Expand Up @@ -30,9 +30,16 @@ export default createRule<Options, MessageIds>({
create(context, [mode]) {
const sourceCode = context.getSourceCode();
return {
VariableDeclarator(node): void {
const lhs = node.id.typeAnnotation?.typeAnnotation;
const rhs = node.init;
'VariableDeclarator,PropertyDefinition'(
node: TSESTree.VariableDeclarator | TSESTree.PropertyDefinition,
): void {
const lhs = (
node.type === AST_NODE_TYPES.VariableDeclarator ? node.id : node
).typeAnnotation?.typeAnnotation;
const rhs =
node.type === AST_NODE_TYPES.VariableDeclarator
? node.init
: node.value;
if (
!rhs ||
rhs.type !== AST_NODE_TYPES.NewExpression ||
Expand All @@ -57,9 +64,25 @@ export default createRule<Options, MessageIds>({
node,
messageId: 'preferTypeAnnotation',
fix(fixer) {
function getIDToAttachAnnotation():
| TSESTree.Token
| TSESTree.Node {
if (node.type === AST_NODE_TYPES.VariableDeclarator) {
return node.id;
}
if (!node.computed) {
return node.key;
}
// If the property's computed, we have to attach the
// annotation after the square bracket, not the enclosed expression
return sourceCode.getTokenAfter(node.key)!;
}
return [
fixer.remove(typeParameters),
fixer.insertTextAfter(node.id, ': ' + typeAnnotation),
fixer.insertTextAfter(
getIDToAttachAnnotation(),
': ' + typeAnnotation,
),
];
},
});
Expand Down
Expand Up @@ -19,6 +19,11 @@ ruleTester.run('consistent-generic-constructors', rule, {
'const a: Foo<string> = Foo<string>();',
'const a: Foo<string> = Foo();',
'const a: Foo = Foo<string>();',
`
class Foo {
a = new Foo<string>();
}
`,
// type-annotation
{
code: 'const a = new Foo();',
Expand Down Expand Up @@ -60,6 +65,14 @@ ruleTester.run('consistent-generic-constructors', rule, {
code: 'const a = new (class C<T> {})<string>();',
options: ['type-annotation'],
},
{
code: `
class Foo {
a: Foo<string> = new Foo();
}
`,
options: ['type-annotation'],
},
],
invalid: [
{
Expand Down Expand Up @@ -143,6 +156,40 @@ ruleTester.run('consistent-generic-constructors', rule, {
],
output: noFormat`const a = new \n Foo<string> \n ();`,
},
{
code: `
class Foo {
a: Foo<string> = new Foo();
}
`,
errors: [
{
messageId: 'preferConstructor',
},
],
output: `
class Foo {
a = new Foo<string>();
}
`,
},
{
code: `
class Foo {
[a]: Foo<string> = new Foo();
}
`,
errors: [
{
messageId: 'preferConstructor',
},
],
output: `
class Foo {
[a] = new Foo<string>();
}
`,
},
{
code: 'const a = new Foo<string>();',
options: ['type-annotation'],
Expand Down Expand Up @@ -213,5 +260,59 @@ ruleTester.run('consistent-generic-constructors', rule, {
],
output: noFormat`const a: Foo</* comment */ string, /* another */ number> = new Foo();`,
},
{
code: `
class Foo {
a = new Foo<string>();
}
`,
options: ['type-annotation'],
errors: [
{
messageId: 'preferTypeAnnotation',
},
],
output: `
class Foo {
a: Foo<string> = new Foo();
}
`,
},
{
code: `
class Foo {
[a] = new Foo<string>();
}
`,
options: ['type-annotation'],
errors: [
{
messageId: 'preferTypeAnnotation',
},
],
output: `
class Foo {
[a]: Foo<string> = new Foo();
}
`,
},
{
code: `
class Foo {
[a + b] = new Foo<string>();
}
`,
options: ['type-annotation'],
errors: [
{
messageId: 'preferTypeAnnotation',
},
],
output: `
class Foo {
[a + b]: Foo<string> = new Foo();
}
`,
},
],
});

0 comments on commit 48f996e

Please sign in to comment.