From a5645fc4759a3e593365088e67a4b4e4c9799bb6 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Fri, 17 Feb 2023 14:37:14 -0500 Subject: [PATCH] feat(eslint-plugin): [consistent-generic-ctors] handle default parameters --- .../rules/consistent-generic-constructors.ts | 38 +++- .../consistent-generic-constructors.test.ts | 204 ++++++++++++++++++ 2 files changed, 231 insertions(+), 11 deletions(-) diff --git a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts index 3524da308596..dfcb5d4a63db 100644 --- a/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts +++ b/packages/eslint-plugin/src/rules/consistent-generic-constructors.ts @@ -32,16 +32,32 @@ export default createRule({ 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 || @@ -69,8 +85,8 @@ export default createRule({ 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; diff --git a/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts b/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts index 1ef61f7e55bf..6c53d13861cc 100644 --- a/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-generic-constructors.test.ts @@ -23,6 +23,23 @@ ruleTester.run('consistent-generic-constructors', rule, { class Foo { a = new Foo(); } + `, + ` +function foo(a: Foo = new Foo()) {} + `, + ` +function foo({ a }: Foo = new Foo()) {} + `, + ` +function foo([a]: Foo = new Foo()) {} + `, + ` +class A { + constructor(a: Foo = new Foo()) {} +} + `, + ` +const a = function (a: Foo = new Foo()) {}; `, // type-annotation { @@ -73,6 +90,50 @@ class Foo { `, options: ['type-annotation'], }, + { + code: ` +function foo(a: Foo = new Foo()) {} + `, + options: ['type-annotation'], + }, + { + code: ` +function foo({ a }: Foo = new Foo()) {} + `, + options: ['type-annotation'], + }, + { + code: ` +function foo([a]: Foo = new Foo()) {} + `, + options: ['type-annotation'], + }, + { + code: ` +class A { + constructor(a: Foo = new Foo()) {} +} + `, + options: ['type-annotation'], + }, + { + code: ` +const a = function (a: Foo = new Foo()) {}; + `, + options: ['type-annotation'], + }, + { + code: ` +const [a = new Foo()] = []; + `, + options: ['type-annotation'], + }, + { + code: ` +function a([a = new Foo()]) {} + `, + options: ['type-annotation'], + }, ], invalid: [ { @@ -190,6 +251,75 @@ class Foo { } `, }, + { + code: ` +function foo(a: Foo = new Foo()) {} + `, + errors: [ + { + messageId: 'preferConstructor', + }, + ], + output: ` +function foo(a = new Foo()) {} + `, + }, + { + code: ` +function foo({ a }: Foo = new Foo()) {} + `, + errors: [ + { + messageId: 'preferConstructor', + }, + ], + output: ` +function foo({ a } = new Foo()) {} + `, + }, + { + code: ` +function foo([a]: Foo = new Foo()) {} + `, + errors: [ + { + messageId: 'preferConstructor', + }, + ], + output: ` +function foo([a] = new Foo()) {} + `, + }, + { + code: ` +class A { + constructor(a: Foo = new Foo()) {} +} + `, + errors: [ + { + messageId: 'preferConstructor', + }, + ], + output: ` +class A { + constructor(a = new Foo()) {} +} + `, + }, + { + code: ` +const a = function (a: Foo = new Foo()) {}; + `, + errors: [ + { + messageId: 'preferConstructor', + }, + ], + output: ` +const a = function (a = new Foo()) {}; + `, + }, { code: 'const a = new Foo();', options: ['type-annotation'], @@ -314,5 +444,79 @@ class Foo { } `, }, + { + code: ` +function foo(a = new Foo()) {} + `, + options: ['type-annotation'], + errors: [ + { + messageId: 'preferTypeAnnotation', + }, + ], + output: ` +function foo(a: Foo = new Foo()) {} + `, + }, + { + code: ` +function foo({ a } = new Foo()) {} + `, + options: ['type-annotation'], + errors: [ + { + messageId: 'preferTypeAnnotation', + }, + ], + output: ` +function foo({ a }: Foo = new Foo()) {} + `, + }, + { + code: ` +function foo([a] = new Foo()) {} + `, + options: ['type-annotation'], + errors: [ + { + messageId: 'preferTypeAnnotation', + }, + ], + output: ` +function foo([a]: Foo = new Foo()) {} + `, + }, + { + code: ` +class A { + constructor(a = new Foo()) {} +} + `, + options: ['type-annotation'], + errors: [ + { + messageId: 'preferTypeAnnotation', + }, + ], + output: ` +class A { + constructor(a: Foo = new Foo()) {} +} + `, + }, + { + code: ` +const a = function (a = new Foo()) {}; + `, + options: ['type-annotation'], + errors: [ + { + messageId: 'preferTypeAnnotation', + }, + ], + output: ` +const a = function (a: Foo = new Foo()) {}; + `, + }, ], }); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy