Skip to content

Commit 0108e9c

Browse files
authored
chore: enable no-lonely-if (typescript-eslint#9547)
* no-lonely-if * suppress
1 parent 970f3f1 commit 0108e9c

File tree

9 files changed

+106
-123
lines changed

9 files changed

+106
-123
lines changed

eslint.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ export default tseslint.config(
206206
'error',
207207
{ commentPattern: '.*intentional fallthrough.*' },
208208
],
209+
'no-lonely-if': 'error',
209210
'no-useless-call': 'error',
210211
'no-useless-computed-key': 'error',
211212
'no-void': ['error', { allowAsStatement: true }],

packages/eslint-plugin/src/rules/consistent-type-imports.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -177,25 +177,23 @@ export default createRule<Options, MessageIds>({
177177
// definitely import type { TypeX }
178178
sourceImports.typeOnlyNamedImport = node;
179179
}
180-
} else {
181-
if (
182-
!sourceImports.valueOnlyNamedImport &&
183-
node.specifiers.length &&
184-
node.specifiers.every(
185-
specifier => specifier.type === AST_NODE_TYPES.ImportSpecifier,
186-
)
187-
) {
188-
sourceImports.valueOnlyNamedImport = node;
189-
sourceImports.valueImport = node;
190-
} else if (
191-
!sourceImports.valueImport &&
192-
node.specifiers.some(
193-
specifier =>
194-
specifier.type === AST_NODE_TYPES.ImportDefaultSpecifier,
195-
)
196-
) {
197-
sourceImports.valueImport = node;
198-
}
180+
} else if (
181+
!sourceImports.valueOnlyNamedImport &&
182+
node.specifiers.length &&
183+
node.specifiers.every(
184+
specifier => specifier.type === AST_NODE_TYPES.ImportSpecifier,
185+
)
186+
) {
187+
sourceImports.valueOnlyNamedImport = node;
188+
sourceImports.valueImport = node;
189+
} else if (
190+
!sourceImports.valueImport &&
191+
node.specifiers.some(
192+
specifier =>
193+
specifier.type === AST_NODE_TYPES.ImportDefaultSpecifier,
194+
)
195+
) {
196+
sourceImports.valueImport = node;
199197
}
200198

201199
const typeSpecifiers: TSESTree.ImportClause[] = [];
@@ -732,6 +730,7 @@ export default createRule<Options, MessageIds>({
732730
}
733731
} else {
734732
// The import is both default and named. Insert named on new line because can't mix default type import and named type imports
733+
// eslint-disable-next-line no-lonely-if
735734
if (fixStyle === 'inline-type-imports') {
736735
yield fixer.insertTextBefore(
737736
node,

packages/eslint-plugin/src/rules/func-call-spacing.ts

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -151,29 +151,27 @@ export default createRule<Options, MessageIds>({
151151
messageId: 'unexpectedWhitespace',
152152
});
153153
}
154-
} else {
155-
if (!hasWhitespace) {
156-
context.report({
157-
node,
158-
loc: lastCalleeToken.loc.start,
159-
messageId: 'missing',
160-
fix(fixer) {
161-
return fixer.insertTextBefore(openingParenToken, ' ');
162-
},
163-
});
164-
} else if (!config!.allowNewlines && hasNewline) {
165-
context.report({
166-
node,
167-
loc: lastCalleeToken.loc.start,
168-
messageId: 'unexpectedNewline',
169-
fix(fixer) {
170-
return fixer.replaceTextRange(
171-
[lastCalleeToken.range[1], openingParenToken.range[0]],
172-
' ',
173-
);
174-
},
175-
});
176-
}
154+
} else if (!hasWhitespace) {
155+
context.report({
156+
node,
157+
loc: lastCalleeToken.loc.start,
158+
messageId: 'missing',
159+
fix(fixer) {
160+
return fixer.insertTextBefore(openingParenToken, ' ');
161+
},
162+
});
163+
} else if (!config!.allowNewlines && hasNewline) {
164+
context.report({
165+
node,
166+
loc: lastCalleeToken.loc.start,
167+
messageId: 'unexpectedNewline',
168+
fix(fixer) {
169+
return fixer.replaceTextRange(
170+
[lastCalleeToken.range[1], openingParenToken.range[0]],
171+
' ',
172+
);
173+
},
174+
});
177175
}
178176
}
179177

packages/eslint-plugin/src/rules/member-delimiter-style.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -272,14 +272,12 @@ export default createRule<Options, MessageIds>({
272272
missingDelimiter = true;
273273
messageId = 'unexpectedComma';
274274
}
275-
} else {
276-
if (optsSemi) {
277-
missingDelimiter = true;
278-
messageId = 'expectedSemi';
279-
} else if (optsComma) {
280-
missingDelimiter = true;
281-
messageId = 'expectedComma';
282-
}
275+
} else if (optsSemi) {
276+
missingDelimiter = true;
277+
messageId = 'expectedSemi';
278+
} else if (optsComma) {
279+
missingDelimiter = true;
280+
messageId = 'expectedComma';
283281
}
284282

285283
if (messageId) {

packages/eslint-plugin/src/rules/no-non-null-assertion.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,20 +79,18 @@ export default createRule<[], MessageIds>({
7979
},
8080
});
8181
}
82+
} else if (node.parent.computed) {
83+
// it is x!?.[y].z
84+
suggest.push({
85+
messageId: 'suggestOptionalChain',
86+
fix: removeToken(),
87+
});
8288
} else {
83-
if (node.parent.computed) {
84-
// it is x!?.[y].z
85-
suggest.push({
86-
messageId: 'suggestOptionalChain',
87-
fix: removeToken(),
88-
});
89-
} else {
90-
// it is x!?.y.z
91-
suggest.push({
92-
messageId: 'suggestOptionalChain',
93-
fix: removeToken(),
94-
});
95-
}
89+
// it is x!?.y.z
90+
suggest.push({
91+
messageId: 'suggestOptionalChain',
92+
fix: removeToken(),
93+
});
9694
}
9795
} else if (
9896
node.parent.type === AST_NODE_TYPES.CallExpression &&

packages/eslint-plugin/src/rules/no-unused-vars.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,13 @@ export default createRule<Options, MessageIds>({
267267
) {
268268
continue;
269269
}
270-
} else {
271-
// skip ignored variables
272-
if (
273-
def.name.type === AST_NODE_TYPES.Identifier &&
274-
options.varsIgnorePattern?.test(def.name.name)
275-
) {
276-
continue;
277-
}
270+
}
271+
// skip ignored variables
272+
else if (
273+
def.name.type === AST_NODE_TYPES.Identifier &&
274+
options.varsIgnorePattern?.test(def.name.name)
275+
) {
276+
continue;
278277
}
279278

280279
if (hasRestSpreadSibling(variable)) {

packages/eslint-plugin/src/rules/prefer-optional-chain-utils/analyzeChain.ts

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -219,50 +219,44 @@ function getFixer(
219219
) {
220220
// user has opted-in to the unsafe behavior
221221
useSuggestionFixer = false;
222+
}
223+
// optional chain specifically will union `undefined` into the final type
224+
// so we need to make sure that there is at least one operand that includes
225+
// `undefined`, or else we're going to change the final type - which is
226+
// unsafe and might cause downstream type errors.
227+
else if (
228+
lastOperand.comparisonType === NullishComparisonType.EqualNullOrUndefined ||
229+
lastOperand.comparisonType ===
230+
NullishComparisonType.NotEqualNullOrUndefined ||
231+
lastOperand.comparisonType === NullishComparisonType.StrictEqualUndefined ||
232+
lastOperand.comparisonType ===
233+
NullishComparisonType.NotStrictEqualUndefined ||
234+
(operator === '||' &&
235+
lastOperand.comparisonType === NullishComparisonType.NotBoolean)
236+
) {
237+
// we know the last operand is an equality check - so the change in types
238+
// DOES NOT matter and will not change the runtime result or cause a type
239+
// check error
240+
useSuggestionFixer = false;
222241
} else {
223-
// optional chain specifically will union `undefined` into the final type
224-
// so we need to make sure that there is at least one operand that includes
225-
// `undefined`, or else we're going to change the final type - which is
226-
// unsafe and might cause downstream type errors.
227-
228-
if (
229-
lastOperand.comparisonType ===
230-
NullishComparisonType.EqualNullOrUndefined ||
231-
lastOperand.comparisonType ===
232-
NullishComparisonType.NotEqualNullOrUndefined ||
233-
lastOperand.comparisonType ===
234-
NullishComparisonType.StrictEqualUndefined ||
235-
lastOperand.comparisonType ===
236-
NullishComparisonType.NotStrictEqualUndefined ||
237-
(operator === '||' &&
238-
lastOperand.comparisonType === NullishComparisonType.NotBoolean)
239-
) {
240-
// we know the last operand is an equality check - so the change in types
241-
// DOES NOT matter and will not change the runtime result or cause a type
242-
// check error
243-
useSuggestionFixer = false;
244-
} else {
245-
useSuggestionFixer = true;
246-
247-
for (const operand of chain) {
248-
if (
249-
includesType(parserServices, operand.node, ts.TypeFlags.Undefined)
250-
) {
251-
useSuggestionFixer = false;
252-
break;
253-
}
254-
}
242+
useSuggestionFixer = true;
255243

256-
// TODO - we could further reduce the false-positive rate of this check by
257-
// checking for cases where the change in types don't matter like
258-
// the test location of an if/while/etc statement.
259-
// but it's quite complex to do this without false-negatives, so
260-
// for now we'll just be over-eager with our matching.
261-
//
262-
// it's MUCH better to false-positive here and only provide a
263-
// suggestion fixer, rather than false-negative and autofix to
264-
// broken code.
244+
for (const operand of chain) {
245+
if (includesType(parserServices, operand.node, ts.TypeFlags.Undefined)) {
246+
useSuggestionFixer = false;
247+
break;
248+
}
265249
}
250+
251+
// TODO - we could further reduce the false-positive rate of this check by
252+
// checking for cases where the change in types don't matter like
253+
// the test location of an if/while/etc statement.
254+
// but it's quite complex to do this without false-negatives, so
255+
// for now we'll just be over-eager with our matching.
256+
//
257+
// it's MUCH better to false-positive here and only provide a
258+
// suggestion fixer, rather than false-negative and autofix to
259+
// broken code.
266260
}
267261

268262
// In its most naive form we could just slap `?.` for every single part of the

packages/scope-manager/src/referencer/Referencer.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,8 @@ class Referencer extends Visitor {
531531
protected JSXMemberExpression(node: TSESTree.JSXMemberExpression): void {
532532
if (node.object.type !== AST_NODE_TYPES.JSXIdentifier) {
533533
this.visit(node.object);
534-
} else {
535-
if (node.object.name !== 'this') {
536-
this.visit(node.object);
537-
}
534+
} else if (node.object.name !== 'this') {
535+
this.visit(node.object);
538536
}
539537
// we don't ever reference the property as it's always going to be a property on the thing
540538
}

packages/typescript-estree/src/convert.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -982,13 +982,11 @@ export class Converter {
982982
'Generators are not allowed in an ambient context.',
983983
);
984984
}
985-
} else {
986-
if (!node.body && isGenerator) {
987-
this.#throwError(
988-
node,
989-
'A function signature cannot be declared as a generator.',
990-
);
991-
}
985+
} else if (!node.body && isGenerator) {
986+
this.#throwError(
987+
node,
988+
'A function signature cannot be declared as a generator.',
989+
);
992990
}
993991

994992
const result = this.createNode<

0 commit comments

Comments
 (0)
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