From 3d78fa701897fc773def285a9fc78bad5b78d18b Mon Sep 17 00:00:00 2001 From: Abraham Guo Date: Thu, 11 Jul 2024 00:47:21 -0500 Subject: [PATCH 1/2] prefer-object-spread --- eslint.config.mjs | 1 + packages/eslint-plugin/src/rules/ban-types.ts | 9 ++--- packages/eslint-plugin/src/rules/indent.ts | 37 +++++++++++-------- .../src/rules/no-extra-parens.ts | 2 +- .../src/util/getFunctionHeadLoc.ts | 4 +- .../parser/tests/test-utils/test-utils.ts | 4 +- packages/rule-tester/src/RuleTester.ts | 24 ++++++------ .../tests/eslint-utils/deepMerge.test.ts | 2 +- 8 files changed, 43 insertions(+), 40 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 4c259bee01a1..0c6c030daa46 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -207,6 +207,7 @@ export default tseslint.config( { commentPattern: '.*intentional fallthrough.*' }, ], 'one-var': ['error', 'never'], + 'prefer-object-spread': 'error', // // eslint-plugin-eslint-comment diff --git a/packages/eslint-plugin/src/rules/ban-types.ts b/packages/eslint-plugin/src/rules/ban-types.ts index da2d79716a35..adbb8311621a 100644 --- a/packages/eslint-plugin/src/rules/ban-types.ts +++ b/packages/eslint-plugin/src/rules/ban-types.ts @@ -207,11 +207,10 @@ export default createRule({ create(context, [options]) { const extendDefaults = options.extendDefaults ?? true; const customTypes = options.types ?? {}; - const types = Object.assign( - {}, - extendDefaults ? defaultTypes : {}, - customTypes, - ); + const types = { + ...(extendDefaults && defaultTypes), + ...customTypes, + }; const bannedTypes = new Map( Object.entries(types).map(([type, data]) => [removeSpaces(type), data]), ); diff --git a/packages/eslint-plugin/src/rules/indent.ts b/packages/eslint-plugin/src/rules/indent.ts index 248ecd0d7e8a..c52b761fb745 100644 --- a/packages/eslint-plugin/src/rules/indent.ts +++ b/packages/eslint-plugin/src/rules/indent.ts @@ -181,16 +181,17 @@ export default createRule({ } as TSESTree.PropertyDefinition; } - return Object.assign({}, rules, { + return { + ...rules, // overwrite the base rule here so we can use our KNOWN_NODES list instead - '*:exit'(node: TSESTree.Node) { + '*:exit'(node: TSESTree.Node): void { // For nodes we care about, skip the default handling, because it just marks the node as ignored... if (!KNOWN_NODES.has(node.type)) { rules['*:exit'](node); } }, - VariableDeclaration(node: TSESTree.VariableDeclaration) { + VariableDeclaration(node: TSESTree.VariableDeclaration): void { // https://github.com/typescript-eslint/typescript-eslint/issues/441 if (node.declarations.length === 0) { return; @@ -199,7 +200,7 @@ export default createRule({ return rules.VariableDeclaration(node); }, - TSAsExpression(node: TSESTree.TSAsExpression) { + TSAsExpression(node: TSESTree.TSAsExpression): void { // transform it to a BinaryExpression return rules['BinaryExpression, LogicalExpression']({ type: AST_NODE_TYPES.BinaryExpression, @@ -215,7 +216,7 @@ export default createRule({ }); }, - TSConditionalType(node: TSESTree.TSConditionalType) { + TSConditionalType(node: TSESTree.TSConditionalType): void { // transform it to a ConditionalExpression return rules.ConditionalExpression({ type: AST_NODE_TYPES.ConditionalExpression, @@ -245,7 +246,7 @@ export default createRule({ 'TSEnumDeclaration, TSTypeLiteral'( node: TSESTree.TSEnumDeclaration | TSESTree.TSTypeLiteral, - ) { + ): void { // transform it to an ObjectExpression return rules['ObjectExpression, ObjectPattern']({ type: AST_NODE_TYPES.ObjectExpression, @@ -263,7 +264,9 @@ export default createRule({ }); }, - TSImportEqualsDeclaration(node: TSESTree.TSImportEqualsDeclaration) { + TSImportEqualsDeclaration( + node: TSESTree.TSImportEqualsDeclaration, + ): void { // transform it to an VariableDeclaration // use VariableDeclaration instead of ImportDeclaration because it's essentially the same thing const { id, moduleReference } = node; @@ -317,7 +320,7 @@ export default createRule({ }); }, - TSIndexedAccessType(node: TSESTree.TSIndexedAccessType) { + TSIndexedAccessType(node: TSESTree.TSIndexedAccessType): void { // convert to a MemberExpression return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ type: AST_NODE_TYPES.MemberExpression, @@ -333,7 +336,7 @@ export default createRule({ }); }, - TSInterfaceBody(node: TSESTree.TSInterfaceBody) { + TSInterfaceBody(node: TSESTree.TSInterfaceBody): void { // transform it to an ClassBody return rules['BlockStatement, ClassBody']({ type: AST_NODE_TYPES.ClassBody, @@ -354,7 +357,7 @@ export default createRule({ 'TSInterfaceDeclaration[extends.length > 0]'( node: TSESTree.TSInterfaceDeclaration, - ) { + ): void { // transform it to a ClassDeclaration return rules[ 'ClassDeclaration[superClass], ClassExpression[superClass]' @@ -379,7 +382,7 @@ export default createRule({ }); }, - TSMappedType(node: TSESTree.TSMappedType) { + TSMappedType(node: TSESTree.TSMappedType): void { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const squareBracketStart = context.sourceCode.getTokenBefore( node.typeParameter, @@ -423,7 +426,7 @@ export default createRule({ }); }, - TSModuleBlock(node: TSESTree.TSModuleBlock) { + TSModuleBlock(node: TSESTree.TSModuleBlock): void { // transform it to a BlockStatement return rules['BlockStatement, ClassBody']({ type: AST_NODE_TYPES.BlockStatement, @@ -436,7 +439,7 @@ export default createRule({ }); }, - TSQualifiedName(node: TSESTree.TSQualifiedName) { + TSQualifiedName(node: TSESTree.TSQualifiedName): void { return rules['MemberExpression, JSXMemberExpression, MetaProperty']({ type: AST_NODE_TYPES.MemberExpression, object: node.left as any, @@ -451,7 +454,7 @@ export default createRule({ }); }, - TSTupleType(node: TSESTree.TSTupleType) { + TSTupleType(node: TSESTree.TSTupleType): void { // transform it to an ArrayExpression return rules['ArrayExpression, ArrayPattern']({ type: AST_NODE_TYPES.ArrayExpression, @@ -464,7 +467,9 @@ export default createRule({ }); }, - TSTypeParameterDeclaration(node: TSESTree.TSTypeParameterDeclaration) { + TSTypeParameterDeclaration( + node: TSESTree.TSTypeParameterDeclaration, + ): void { if (!node.params.length) { return; } @@ -487,6 +492,6 @@ export default createRule({ loc: node.loc, }); }, - }); + }; }, }); diff --git a/packages/eslint-plugin/src/rules/no-extra-parens.ts b/packages/eslint-plugin/src/rules/no-extra-parens.ts index 0ed0f4c6b4de..0b5c82d08438 100644 --- a/packages/eslint-plugin/src/rules/no-extra-parens.ts +++ b/packages/eslint-plugin/src/rules/no-extra-parens.ts @@ -303,6 +303,6 @@ export default createRule({ } }, }; - return Object.assign({}, rules, overrides); + return { ...rules, ...overrides }; }, }); diff --git a/packages/eslint-plugin/src/util/getFunctionHeadLoc.ts b/packages/eslint-plugin/src/util/getFunctionHeadLoc.ts index a8f6bc40afbd..cc7b5c5bd7a1 100644 --- a/packages/eslint-plugin/src/util/getFunctionHeadLoc.ts +++ b/packages/eslint-plugin/src/util/getFunctionHeadLoc.ts @@ -197,7 +197,7 @@ export function getFunctionHeadLoc( } return { - start: Object.assign({}, start), - end: Object.assign({}, end), + start: { ...start }, + end: { ...end }, }; } diff --git a/packages/parser/tests/test-utils/test-utils.ts b/packages/parser/tests/test-utils/test-utils.ts index 4d86b0d17cf3..ae5da03d59bd 100644 --- a/packages/parser/tests/test-utils/test-utils.ts +++ b/packages/parser/tests/test-utils/test-utils.ts @@ -40,7 +40,7 @@ export function createSnapshotTestBlock( code: string, config: ParserOptions = {}, ): () => void { - config = Object.assign({}, defaultConfig, config); + config = { ...defaultConfig, ...config }; /** * @returns the AST object @@ -72,7 +72,7 @@ export function createSnapshotTestBlock( * @param config The configuration object for the parser */ export function testServices(code: string, config: ParserOptions = {}): void { - config = Object.assign({}, defaultConfig, config); + config = { ...defaultConfig, ...config }; const services = parser.parseForESLint(code, config).services; expect(services).toBeDefined(); diff --git a/packages/rule-tester/src/RuleTester.ts b/packages/rule-tester/src/RuleTester.ts index ae926072ab03..dc319dcf9bcc 100644 --- a/packages/rule-tester/src/RuleTester.ts +++ b/packages/rule-tester/src/RuleTester.ts @@ -399,19 +399,17 @@ export class RuleTester extends TestFramework { emitLegacyRuleAPIWarning(ruleName); } - this.#linter.defineRule( - ruleName, - Object.assign({}, rule, { - // Create a wrapper rule that freezes the `context` properties. - create(context: RuleContext) { - freezeDeeply(context.options); - freezeDeeply(context.settings); - freezeDeeply(context.parserOptions); - - return (typeof rule === 'function' ? rule : rule.create)(context); - }, - }), - ); + this.#linter.defineRule(ruleName, { + ...rule, + // Create a wrapper rule that freezes the `context` properties. + create(context: RuleContext) { + freezeDeeply(context.options); + freezeDeeply(context.settings); + freezeDeeply(context.parserOptions); + + return (typeof rule === 'function' ? rule : rule.create)(context); + }, + }); this.#linter.defineRules(this.#rules); diff --git a/packages/utils/tests/eslint-utils/deepMerge.test.ts b/packages/utils/tests/eslint-utils/deepMerge.test.ts index 26fb02e3bc4d..27c671c99aae 100644 --- a/packages/utils/tests/eslint-utils/deepMerge.test.ts +++ b/packages/utils/tests/eslint-utils/deepMerge.test.ts @@ -38,7 +38,7 @@ describe('deepMerge', () => { }, }; - expect(ESLintUtils.deepMerge(a, b)).toStrictEqual(Object.assign({}, a, b)); + expect(ESLintUtils.deepMerge(a, b)).toStrictEqual({ ...a, ...b }); }); it('deeply overwrites properties in the first one with the second', () => { From 987c2dd03fdbc8a0ffdfc5bdeb4c450074b39570 Mon Sep 17 00:00:00 2001 From: Abraham Guo Date: Thu, 11 Jul 2024 00:51:55 -0500 Subject: [PATCH 2/2] as const --- packages/parser/tests/test-utils/test-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/parser/tests/test-utils/test-utils.ts b/packages/parser/tests/test-utils/test-utils.ts index ae5da03d59bd..a78f11dd3296 100644 --- a/packages/parser/tests/test-utils/test-utils.ts +++ b/packages/parser/tests/test-utils/test-utils.ts @@ -10,7 +10,7 @@ const defaultConfig = { tokens: true, comment: true, errorOnUnknownASTType: true, - sourceType: 'module', + sourceType: 'module' as const, }; /**