Content-Length: 9212 | pFad | http://github.com/typescript-eslint/typescript-eslint/pull/11272.diff
thub.com
diff --git a/packages/eslint-plugin/docs/rules/prefer-optional-chain.mdx b/packages/eslint-plugin/docs/rules/prefer-optional-chain.mdx
index 777c80068e69..6fa0720ba2c3 100644
--- a/packages/eslint-plugin/docs/rules/prefer-optional-chain.mdx
+++ b/packages/eslint-plugin/docs/rules/prefer-optional-chain.mdx
@@ -265,6 +265,37 @@ thing?.toString();
+### `checkVoid`
+
+{/* insert option description */}
+
+Examples of code for this rule with `{ checkVoid: true }`:
+
+
+
+
+```ts option='{ "checkVoid": true }'
+declare const thing: {
+ method: undefined | (() => void);
+};
+
+thing.method && thing.method();
+```
+
+
+
+
+```ts option='{ "checkVoid": true }'
+declare const thing: {
+ method: undefined | (() => void);
+};
+
+thing.method?.();
+```
+
+
+
+
### `requireNullish`
{/* insert option description */}
diff --git a/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/PreferOptionalChainOptions.ts b/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/PreferOptionalChainOptions.ts
index de1147b54447..c799268477ee 100644
--- a/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/PreferOptionalChainOptions.ts
+++ b/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/PreferOptionalChainOptions.ts
@@ -10,5 +10,6 @@ export interface PreferOptionalChainOptions {
checkNumber?: boolean;
checkString?: boolean;
checkUnknown?: boolean;
+ checkVoid?: boolean;
requireNullish?: boolean;
}
diff --git a/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/gatherLogicalOperands.ts b/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/gatherLogicalOperands.ts
index 174f8982cad8..ab6f90b121a9 100644
--- a/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/gatherLogicalOperands.ts
+++ b/packages/eslint-plugin/src/rules/prefer-optional-chain-utils/gatherLogicalOperands.ts
@@ -59,8 +59,6 @@ export interface InvalidOperand {
type: OperandValidity.Invalid;
}
type Operand = InvalidOperand | ValidOperand;
-
-const NULLISH_FLAGS = ts.TypeFlags.Null | ts.TypeFlags.Undefined;
function isValidFalseBooleanCheckType(
node: TSESTree.Node,
disallowFalseyLiteral: boolean,
@@ -92,26 +90,30 @@ function isValidFalseBooleanCheckType(
return false;
}
- let allowedFlags = NULLISH_FLAGS | ts.TypeFlags.Object;
- if (options.checkAny === true) {
- allowedFlags |= ts.TypeFlags.Any;
+ let flagsToExcludeFromCheck = 0;
+ if (options.checkAny !== true) {
+ flagsToExcludeFromCheck |= ts.TypeFlags.Any;
+ }
+ if (options.checkUnknown !== true) {
+ flagsToExcludeFromCheck |= ts.TypeFlags.Unknown;
}
- if (options.checkUnknown === true) {
- allowedFlags |= ts.TypeFlags.Unknown;
+ if (options.checkString !== true) {
+ flagsToExcludeFromCheck |= ts.TypeFlags.StringLike;
}
- if (options.checkString === true) {
- allowedFlags |= ts.TypeFlags.StringLike;
+ if (options.checkNumber !== true) {
+ flagsToExcludeFromCheck |= ts.TypeFlags.NumberLike;
}
- if (options.checkNumber === true) {
- allowedFlags |= ts.TypeFlags.NumberLike;
+ if (options.checkBoolean !== true) {
+ flagsToExcludeFromCheck |= ts.TypeFlags.BooleanLike;
}
- if (options.checkBoolean === true) {
- allowedFlags |= ts.TypeFlags.BooleanLike;
+ if (options.checkBigInt !== true) {
+ flagsToExcludeFromCheck |= ts.TypeFlags.BigIntLike;
}
- if (options.checkBigInt === true) {
- allowedFlags |= ts.TypeFlags.BigIntLike;
+ if (options.checkVoid !== true) {
+ flagsToExcludeFromCheck |= ts.TypeFlags.Void;
}
- return types.every(t => isTypeFlagSet(t, allowedFlags));
+
+ return types.every(t => !isTypeFlagSet(t, flagsToExcludeFromCheck));
}
export function gatherLogicalOperands(
diff --git a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts
index 241f4240e78d..ba58a314f75a 100644
--- a/packages/eslint-plugin/src/rules/prefer-optional-chain.ts
+++ b/packages/eslint-plugin/src/rules/prefer-optional-chain.ts
@@ -82,6 +82,11 @@ export default createRule<
description:
'Check operands that are typed as `unknown` when inspecting "loose boolean" operands.',
},
+ checkVoid: {
+ type: 'boolean',
+ description:
+ 'Check operands that are typed as `void` when inspecting "loose boolean" operands.',
+ },
requireNullish: {
type: 'boolean',
description:
@@ -100,6 +105,7 @@ export default createRule<
checkNumber: true,
checkString: true,
checkUnknown: true,
+ checkVoid: true,
requireNullish: false,
},
],
diff --git a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/prefer-optional-chain.shot b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/prefer-optional-chain.shot
index 8607ddca5bca..032898689ebb 100644
--- a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/prefer-optional-chain.shot
+++ b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/prefer-optional-chain.shot
@@ -149,6 +149,25 @@ declare const thing: bigint;
thing?.toString();
+Incorrect
+Options: { "checkVoid": true }
+
+declare const thing: {
+ method: undefined | (() => void);
+};
+
+thing.method && thing.method();
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Prefer using an optional chain expression instead, as it's more concise and easier to read.
+
+Correct
+Options: { "checkVoid": true }
+
+declare const thing: {
+ method: undefined | (() => void);
+};
+
+thing.method?.();
+
Incorrect
Options: { "requireNullish": true }
diff --git a/packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts b/packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts
index c05f6218b24c..caf2a232b554 100644
--- a/packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts
+++ b/packages/eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts
@@ -1680,6 +1680,48 @@ describe('hand-crafted cases', () => {
],
output: 'a?.prop;',
},
+ // check void
+ {
+ code: `
+declare const foo: {
+ method: undefined | (() => void);
+};
+foo.method && foo.method();
+ `,
+ errors: [{ messageId: 'preferOptionalChain' }],
+ output: `
+declare const foo: {
+ method: undefined | (() => void);
+};
+foo.method?.();
+ `,
+ },
+ // Exclude for everything else, an error occurs
+ {
+ code: noFormat`declare const foo: { x: { y: string } } | null; foo && foo.x;`,
+ errors: [
+ {
+ messageId: 'preferOptionalChain',
+ suggestions: [
+ {
+ messageId: 'optionalChainSuggest',
+ output: `declare const foo: { x: { y: string } } | null; foo?.x;`,
+ },
+ ],
+ },
+ ],
+ options: [
+ {
+ checkAny: false,
+ checkBigInt: false,
+ checkBoolean: false,
+ checkNumber: false,
+ checkString: false,
+ checkUnknown: false,
+ checkVoid: false,
+ },
+ ],
+ },
],
valid: [
'!a || !b;',
@@ -1878,6 +1920,15 @@ describe('hand-crafted cases', () => {
`,
options: [{ checkUnknown: false }],
},
+ {
+ code: `
+declare const foo: {
+ method: undefined | (() => void);
+};
+foo.method && foo.method();
+ `,
+ options: [{ checkVoid: false }],
+ },
'(x = {}) && (x.y = true) != null && x.y.toString();',
"('x' as `${'x'}`) && ('x' as `${'x'}`).length;",
'`x` && `x`.length;',
diff --git a/packages/eslint-plugin/tests/schema-snapshots/prefer-optional-chain.shot b/packages/eslint-plugin/tests/schema-snapshots/prefer-optional-chain.shot
index 7d300bdbdfdd..8ec3cc46b7b5 100644
--- a/packages/eslint-plugin/tests/schema-snapshots/prefer-optional-chain.shot
+++ b/packages/eslint-plugin/tests/schema-snapshots/prefer-optional-chain.shot
@@ -33,6 +33,10 @@
"description": "Check operands that are typed as `unknown` when inspecting \"loose boolean\" operands.",
"type": "boolean"
},
+ "checkVoid": {
+ "description": "Check operands that are typed as `void` when inspecting \"loose boolean\" operands.",
+ "type": "boolean"
+ },
"requireNullish": {
"description": "Skip operands that are not typed with `null` and/or `undefined` when inspecting \"loose boolean\" operands.",
"type": "boolean"
@@ -61,6 +65,8 @@ type Options = [
checkString?: boolean;
/** Check operands that are typed as `unknown` when inspecting "loose boolean" operands. */
checkUnknown?: boolean;
+ /** Check operands that are typed as `void` when inspecting "loose boolean" operands. */
+ checkVoid?: boolean;
/** Skip operands that are not typed with `null` and/or `undefined` when inspecting "loose boolean" operands. */
requireNullish?: boolean;
},
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/typescript-eslint/typescript-eslint/pull/11272.diff
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy