diff --git a/packages/eslint-plugin/src/rules/space-infix-ops.ts b/packages/eslint-plugin/src/rules/space-infix-ops.ts index a43ba5c30ab..9cab8d27f52 100644 --- a/packages/eslint-plugin/src/rules/space-infix-ops.ts +++ b/packages/eslint-plugin/src/rules/space-infix-ops.ts @@ -36,13 +36,9 @@ export default util.createRule({ const rules = baseRule.create(context); const sourceCode = context.getSourceCode(); - const report = ( - node: TSESTree.Node | TSESTree.Token, - operator: TSESTree.Token, - ): void => { + function report(operator: TSESTree.Token): void { context.report({ - node: node, - loc: operator.loc, + node: operator, messageId: 'missingSpace', data: { operator: operator.value, @@ -65,21 +61,19 @@ export default util.createRule({ return fixer.replaceText(operator, fixString); }, }); - }; + } function isSpaceChar(token: TSESTree.Token): boolean { return ( - token.type === AST_TOKEN_TYPES.Punctuator && - /^[=|?|:]$/.test(token.value) + token.type === AST_TOKEN_TYPES.Punctuator && /^[=?:]$/.test(token.value) ); } function checkAndReportAssignmentSpace( - node: TSESTree.Node, - leftNode: TSESTree.Token, - rightNode?: TSESTree.Token | null, + leftNode: TSESTree.Token | TSESTree.Node | null, + rightNode?: TSESTree.Token | TSESTree.Node | null, ): void { - if (!rightNode) { + if (!rightNode || !leftNode) { return; } @@ -87,16 +81,16 @@ export default util.createRule({ leftNode, rightNode, isSpaceChar, - ); + )!; - const prev = sourceCode.getTokenBefore(operator!); - const next = sourceCode.getTokenAfter(operator!); + const prev = sourceCode.getTokenBefore(operator)!; + const next = sourceCode.getTokenAfter(operator)!; if ( - !sourceCode.isSpaceBetween!(prev!, operator!) || - !sourceCode.isSpaceBetween!(operator!, next!) + !sourceCode.isSpaceBetween!(prev, operator) || + !sourceCode.isSpaceBetween!(operator, next) ) { - report(node, operator!); + report(operator); } } @@ -105,16 +99,7 @@ export default util.createRule({ * @param node The node to report */ function checkForEnumAssignmentSpace(node: TSESTree.TSEnumMember): void { - if (!node.initializer) { - return; - } - - const leftNode = sourceCode.getTokenByRangeStart(node.id.range[0])!; - const rightNode = sourceCode.getTokenByRangeStart( - node.initializer.range[0], - )!; - - checkAndReportAssignmentSpace(node, leftNode, rightNode); + checkAndReportAssignmentSpace(node.id, node.initializer); } /** @@ -124,14 +109,12 @@ export default util.createRule({ function checkForPropertyDefinitionAssignmentSpace( node: TSESTree.PropertyDefinition, ): void { - const leftNode = sourceCode.getLastToken( - node.typeAnnotation ?? node.key, - )!; - const rightNode = node.value - ? sourceCode.getTokenByRangeStart(node.value.range[0]) - : undefined; + const leftNode = + node.optional && !node.typeAnnotation + ? sourceCode.getTokenAfter(node.key) + : node.typeAnnotation ?? node.key; - checkAndReportAssignmentSpace(node, leftNode, rightNode); + checkAndReportAssignmentSpace(leftNode, node.value); } /** @@ -161,7 +144,7 @@ export default util.createRule({ !sourceCode.isSpaceBetween!(prev!, operator) || !sourceCode.isSpaceBetween!(operator, next!) ) { - report(typeAnnotation, operator); + report(operator); } } }); @@ -174,20 +157,15 @@ export default util.createRule({ function checkForTypeAliasAssignment( node: TSESTree.TSTypeAliasDeclaration, ): void { - const leftNode = sourceCode.getLastToken(node.typeParameters ?? node.id)!; - const rightNode = sourceCode.getFirstToken(node.typeAnnotation); - - checkAndReportAssignmentSpace(node, leftNode, rightNode); + checkAndReportAssignmentSpace( + node.typeParameters ?? node.id, + node.typeAnnotation, + ); } function checkForTypeConditional(node: TSESTree.TSConditionalType): void { - const extendsLastToken = sourceCode.getLastToken(node.extendsType)!; - const trueFirstToken = sourceCode.getFirstToken(node.trueType)!; - const trueLastToken = sourceCode.getLastToken(node.trueType)!; - const falseFirstToken = sourceCode.getFirstToken(node.falseType)!; - - checkAndReportAssignmentSpace(node, extendsLastToken, trueFirstToken); - checkAndReportAssignmentSpace(node, trueLastToken, falseFirstToken); + checkAndReportAssignmentSpace(node.extendsType, node.trueType); + checkAndReportAssignmentSpace(node.trueType, node.falseType); } return { diff --git a/packages/eslint-plugin/tests/rules/space-infix-ops.test.ts b/packages/eslint-plugin/tests/rules/space-infix-ops.test.ts index e8b5fa2bc93..37060fab745 100644 --- a/packages/eslint-plugin/tests/rules/space-infix-ops.test.ts +++ b/packages/eslint-plugin/tests/rules/space-infix-ops.test.ts @@ -165,6 +165,20 @@ ruleTester.run('space-infix-ops', rule, { } `, }, + { + code: ` + class Test { + value: string & number; + } + `, + }, + { + code: ` + class Test { + optional? = false; + } + `, + }, { code: ` type Test = @@ -379,13 +393,6 @@ ruleTester.run('space-infix-ops', rule, { const x: string & (((() => void))); `, }, - { - code: ` - class Test { - value: string & number; - } - `, - }, { code: ` function foo() {} @@ -984,6 +991,91 @@ ruleTester.run('space-infix-ops', rule, { }, ], }, + { + code: ` + type Test = |string|(((() => void)))|string; + `, + output: ` + type Test = | string | (((() => void))) | string; + `, + errors: [ + { + messageId: 'missingSpace', + column: 21, + line: 2, + }, + { + messageId: 'missingSpace', + column: 28, + line: 2, + }, + { + messageId: 'missingSpace', + column: 45, + line: 2, + }, + ], + }, + { + code: ` + type Test=|string|(((() => void)))|string; + `, + output: ` + type Test = |string | (((() => void))) | string; + `, + errors: [ + { + messageId: 'missingSpace', + column: 18, + line: 2, + }, + { + messageId: 'missingSpace', + column: 19, + line: 2, + }, + { + messageId: 'missingSpace', + column: 26, + line: 2, + }, + { + messageId: 'missingSpace', + column: 43, + line: 2, + }, + ], + }, + { + code: ` + type Test=(string&number)|string|(((() => void))); + `, + output: ` + type Test = (string & number) | string | (((() => void))); + `, + errors: [ + { + messageId: 'missingSpace', + column: 18, + line: 2, + }, + { + messageId: 'missingSpace', + column: 26, + line: 2, + }, + { + messageId: 'missingSpace', + column: 34, + line: 2, + }, + { + messageId: 'missingSpace', + column: 41, + line: 2, + }, + ], + }, { code: ` type Test = @@ -1861,6 +1953,25 @@ ruleTester.run('space-infix-ops', rule, { }, ], }, + { + code: ` + class Test { + optional?= false; + } + `, + output: ` + class Test { + optional? = false; + } + `, + errors: [ + { + messageId: 'missingSpace', + column: 20, + line: 3, + }, + ], + }, { code: ` function foo() {}