Skip to content

Commit

Permalink
feat(eslint-plugin): [consistent-generic-constructors] handle default…
Browse files Browse the repository at this point in the history
… parameters (#6484)

feat(eslint-plugin): [consistent-generic-ctors] handle default parameters
  • Loading branch information
Josh-Cena committed Feb 20, 2023
1 parent 16144d1 commit e8cebce
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 11 deletions.
38 changes: 27 additions & 11 deletions packages/eslint-plugin/src/rules/consistent-generic-constructors.ts
Expand Up @@ -32,16 +32,32 @@ export default createRule<Options, MessageIds>({
create(context, [mode]) {
const sourceCode = context.getSourceCode();
return {
'VariableDeclarator,PropertyDefinition'(
node: TSESTree.VariableDeclarator | TSESTree.PropertyDefinition,
'VariableDeclarator,PropertyDefinition,:matches(FunctionDeclaration,FunctionExpression) > AssignmentPattern'(
node:
| TSESTree.VariableDeclarator
| TSESTree.PropertyDefinition
| TSESTree.AssignmentPattern,
): 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;
function getLHSRHS(): [
TSESTree.BindingName | TSESTree.PropertyDefinition,
TSESTree.Expression | null,
] {
switch (node.type) {
case AST_NODE_TYPES.VariableDeclarator:
return [node.id, node.init];
case AST_NODE_TYPES.PropertyDefinition:
return [node, node.value];
case AST_NODE_TYPES.AssignmentPattern:
return [node.left, node.right];
default:
throw new Error(
`Unhandled node type: ${(node as { type: string }).type}`,
);
}
}
const [lhsName, rhs] = getLHSRHS();
const lhs = lhsName.typeAnnotation?.typeAnnotation;

if (
!rhs ||
rhs.type !== AST_NODE_TYPES.NewExpression ||
Expand Down Expand Up @@ -69,8 +85,8 @@ export default createRule<Options, MessageIds>({
function getIDToAttachAnnotation():
| TSESTree.Token
| TSESTree.Node {
if (node.type === AST_NODE_TYPES.VariableDeclarator) {
return node.id;
if (node.type !== AST_NODE_TYPES.PropertyDefinition) {
return lhsName;
}
if (!node.computed) {
return node.key;
Expand Down
Expand Up @@ -23,6 +23,23 @@ ruleTester.run('consistent-generic-constructors', rule, {
class Foo {
a = new Foo<string>();
}
`,
`
function foo(a: Foo = new Foo<string>()) {}
`,
`
function foo({ a }: Foo = new Foo<string>()) {}
`,
`
function foo([a]: Foo = new Foo<string>()) {}
`,
`
class A {
constructor(a: Foo = new Foo<string>()) {}
}
`,
`
const a = function (a: Foo = new Foo<string>()) {};
`,
// type-annotation
{
Expand Down Expand Up @@ -73,6 +90,50 @@ class Foo {
`,
options: ['type-annotation'],
},
{
code: `
function foo(a: Foo<string> = new Foo()) {}
`,
options: ['type-annotation'],
},
{
code: `
function foo({ a }: Foo<string> = new Foo()) {}
`,
options: ['type-annotation'],
},
{
code: `
function foo([a]: Foo<string> = new Foo()) {}
`,
options: ['type-annotation'],
},
{
code: `
class A {
constructor(a: Foo<string> = new Foo()) {}
}
`,
options: ['type-annotation'],
},
{
code: `
const a = function (a: Foo<string> = new Foo()) {};
`,
options: ['type-annotation'],
},
{
code: `
const [a = new Foo<string>()] = [];
`,
options: ['type-annotation'],
},
{
code: `
function a([a = new Foo<string>()]) {}
`,
options: ['type-annotation'],
},
],
invalid: [
{
Expand Down Expand Up @@ -190,6 +251,75 @@ class Foo {
}
`,
},
{
code: `
function foo(a: Foo<string> = new Foo()) {}
`,
errors: [
{
messageId: 'preferConstructor',
},
],
output: `
function foo(a = new Foo<string>()) {}
`,
},
{
code: `
function foo({ a }: Foo<string> = new Foo()) {}
`,
errors: [
{
messageId: 'preferConstructor',
},
],
output: `
function foo({ a } = new Foo<string>()) {}
`,
},
{
code: `
function foo([a]: Foo<string> = new Foo()) {}
`,
errors: [
{
messageId: 'preferConstructor',
},
],
output: `
function foo([a] = new Foo<string>()) {}
`,
},
{
code: `
class A {
constructor(a: Foo<string> = new Foo()) {}
}
`,
errors: [
{
messageId: 'preferConstructor',
},
],
output: `
class A {
constructor(a = new Foo<string>()) {}
}
`,
},
{
code: `
const a = function (a: Foo<string> = new Foo()) {};
`,
errors: [
{
messageId: 'preferConstructor',
},
],
output: `
const a = function (a = new Foo<string>()) {};
`,
},
{
code: 'const a = new Foo<string>();',
options: ['type-annotation'],
Expand Down Expand Up @@ -314,5 +444,79 @@ class Foo {
}
`,
},
{
code: `
function foo(a = new Foo<string>()) {}
`,
options: ['type-annotation'],
errors: [
{
messageId: 'preferTypeAnnotation',
},
],
output: `
function foo(a: Foo<string> = new Foo()) {}
`,
},
{
code: `
function foo({ a } = new Foo<string>()) {}
`,
options: ['type-annotation'],
errors: [
{
messageId: 'preferTypeAnnotation',
},
],
output: `
function foo({ a }: Foo<string> = new Foo()) {}
`,
},
{
code: `
function foo([a] = new Foo<string>()) {}
`,
options: ['type-annotation'],
errors: [
{
messageId: 'preferTypeAnnotation',
},
],
output: `
function foo([a]: Foo<string> = new Foo()) {}
`,
},
{
code: `
class A {
constructor(a = new Foo<string>()) {}
}
`,
options: ['type-annotation'],
errors: [
{
messageId: 'preferTypeAnnotation',
},
],
output: `
class A {
constructor(a: Foo<string> = new Foo()) {}
}
`,
},
{
code: `
const a = function (a = new Foo<string>()) {};
`,
options: ['type-annotation'],
errors: [
{
messageId: 'preferTypeAnnotation',
},
],
output: `
const a = function (a: Foo<string> = new Foo()) {};
`,
},
],
});

0 comments on commit e8cebce

Please sign in to comment.