8000 chore: enable no-lonely-if (#9547) · abrahamguo/typescript-eslint@0108e9c · GitHub
[go: up one dir, main page]

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