Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0913f40

Browse files
author
Josh Goldberg
authored
fix(eslint-plugin): [strict-boolean-expressions] account for truthy literals (typescript-eslint#3236)
1 parent 0221476 commit 0913f40

File tree

2 files changed

+85
-15
lines changed

2 files changed

+85
-15
lines changed

packages/eslint-plugin/src/rules/strict-boolean-expressions.ts

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,16 @@ export default util.createRule<Options, MessageId>({
308308
return;
309309
}
310310

311+
// Known edge case: truthy primitives and nullish values are always valid boolean expressions
312+
if (
313+
(options.allowNumber && is('nullish', 'truthy number')) ||
314+
(options.allowString && is('nullish', 'truthy string'))
315+
) {
316+
return;
317+
}
318+
311319
// string
312-
if (is('string')) {
320+
if (is('string') || is('truthy string')) {
313321
if (!options.allowString) {
314322
if (isLogicalNegationExpression(node.parent!)) {
315323
// if (!string)
@@ -458,7 +466,7 @@ export default util.createRule<Options, MessageId>({
458466
}
459467

460468
// number
461-
if (is('number')) {
469+
if (is('number') || is('truthy number')) {
462470
if (!options.allowNumber) {
463471
if (isArrayLengthExpression(node, typeChecker, parserServices)) {
464472
if (isLogicalNegationExpression(node.parent!)) {
@@ -701,7 +709,9 @@ export default util.createRule<Options, MessageId>({
701709
| 'nullish'
702710
| 'boolean'
703711
| 'string'
712+
| 'truthy string'
704713
| 'number'
714+
| 'truthy number'
705715
| 'object'
706716
| 'any'
707717
| 'never';
@@ -731,21 +741,30 @@ export default util.createRule<Options, MessageId>({
731741
variantTypes.add('boolean');
732742
}
733743

734-
if (
735-
types.some(type => tsutils.isTypeFlagSet(type, ts.TypeFlags.StringLike))
736-
) {
737-
variantTypes.add('string');
744+
const strings = types.filter(type =>
745+
tsutils.isTypeFlagSet(type, ts.TypeFlags.StringLike),
746+
);
747+
748+
if (strings.length) {
749+
if (strings.some(type => type.isStringLiteral() && type.value !== '')) {
750+
variantTypes.add('truthy string');
751+
} else {
752+
variantTypes.add('string');
753+
}
738754
}
739755

740-
if (
741-
types.some(type =>
742-
tsutils.isTypeFlagSet(
743-
type,
744-
ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLike,
745-
),
746-
)
747-
) {
748-
variantTypes.add('number');
756+
const numbers = types.filter(type =>
757+
tsutils.isTypeFlagSet(
758+
type,
759+
ts.TypeFlags.NumberLike | ts.TypeFlags.BigIntLike,
760+
),
761+
);
762+
if (numbers.length) {
763+
if (numbers.some(type => type.isNumberLiteral() && type.value !== 0)) {
764+
variantTypes.add('truthy number');
765+
} else {
766+
variantTypes.add('number');
767+
}
749768
}
750769

751770
if (

packages/eslint-plugin/tests/rules/strict-boolean-expressions.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,57 @@ if (x) {
133133
tsconfigRootDir: path.join(rootPath, 'unstrict'),
134134
},
135135
},
136+
137+
`
138+
function f(arg: 'a' | null) {
139+
if (arg) console.log(arg);
140+
}
141+
`,
142+
`
143+
function f(arg: 'a' | 'b' | null) {
144+
if (arg) console.log(arg);
145+
}
146+
`,
147+
{
148+
code: `
149+
declare const x: 1 | null;
150+
declare const y: 1;
151+
if (x) {
152+
}
153+
if (y) {
154+
}
155+
`,
156+
options: [
157+
{
158+
allowNumber: true,
159+
},
160+
],
161+
},
162+
`
163+
function f(arg: 1 | null) {
164+
if (arg) console.log(arg);
165+
}
166+
`,
167+
`
168+
function f(arg: 1 | 2 | null) {
169+
if (arg) console.log(arg);
170+
}
171+
`,
172+
{
173+
code: `
174+
declare const x: 'a' | null;
175+
declare const y: 'a';
176+
if (x) {
177+
}
178+
if (y) {
179+
}
180+
`,
181+
options: [
182+
{
183+
allowString: true,
184+
},
185+
],
186+
},
136187
],
137188

138189
invalid: [

0 commit comments

Comments
 (0)