Repository: eslint/eslint
File: lib/rules/no-implicit-coercion.js (JavaScript)

Code before:

                    report(node, recommendation, true);
                }

                // ~foo.indexOf(bar)
                operatorAllowed = options.allow.includes("~");
                if (!operatorAllowed && options.boolean && isBinaryNegatingOfIndexOf(node)) {

                    // `foo?.indexOf(bar) !== -1` will be true (== found) if the `foo` is nullish. So use `>= 0` in that case.
                    const comparison = node.argument.type === "ChainExpression" ? ">= 0" : "!== -1";
                    const recommendation = `${sourceCode.getText(node.argument)} ${comparison}`;

                    report(node, recommendation, false);
                }

                // +foo
                operatorAllowed = options.allow.includes("+");
                if (!operatorAllowed && options.number && node.operator === "+" && !isNumeric(node.argument)) {
                    const recommendation = `Number(${sourceCode.getText(node.argument)})`;

                    report(node, recommendation, true);
                }

                // -(-foo)
                operatorAllowed = options.allow.includes("- -");
                if (!operatorAllowed && node.operator === "-" && node.argument.type === "UnaryExpression" && node.argument.operator === "-") {
                    const recommendation = `Number(${sourceCode.getText(node.argument.argument)})`;

                    report(node, recommendation, true);
                }
            },

            // Use `:exit` to prevent double reporting
            "BinaryExpression:exit"(node) {
                let operatorAllowed;

                // 1 * foo
                operatorAllowed = options.allow.includes("*");
                const nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && !isMultiplyByFractionOfOne(node, sourceCode) &&
                    getNonNumericOperand(node);

                if (nonNumericOperand) {
                    const recommendation = `Number(${sourceCode.getText(nonNumericOperand)})`;

                    report(node, recommendation, true);
                }

                // foo - 0
                operatorAllowed = options.allow.includes("-");
                if (!operatorAllowed && node.operator === "-" && isNumeric(node.right) && node.right.value === 0) {
                    const recommendation = `Number(${sourceCode.getText(node.left)})`;

Review comment (suggestion):
I think we should honor the [`number` option](https://deploy-preview-17832--docs-eslint.netlify.app/rules/no-implicit-coercion#options):

```suggestion
                if (!operatorAllowed && options.number && node.operator === "-" && node.argument.type === "UnaryExpression" && node.argument.operator === "-") {
```

Maybe we can add valid test cases [here](https://github.com/eslint/eslint/blob/70a686b/tests/lib/rules/no-implicit-coercion.js#L69-L80) to make sure that no problem is reported when `number` is set to `false`, or when `allow` contains `"- -"`, e.g.:


Code after:

                    report(node, recommendation, true);
                }

                // ~foo.indexOf(bar)
                operatorAllowed = options.allow.includes("~");
                if (!operatorAllowed && options.boolean && isBinaryNegatingOfIndexOf(node)) {

                    // `foo?.indexOf(bar) !== -1` will be true (== found) if the `foo` is nullish. So use `>= 0` in that case.
                    const comparison = node.argument.type === "ChainExpression" ? ">= 0" : "!== -1";
                    const recommendation = `${sourceCode.getText(node.argument)} ${comparison}`;

                    report(node, recommendation, false);
                }

                // +foo
                operatorAllowed = options.allow.includes("+");
                if (!operatorAllowed && options.number && node.operator === "+" && !isNumeric(node.argument)) {
                    const recommendation = `Number(${sourceCode.getText(node.argument)})`;

                    report(node, recommendation, true);
                }

                // -(-foo)
                operatorAllowed = options.allow.includes("- -");
                if (!operatorAllowed && options.number && node.operator === "-" && node.argument.type === "UnaryExpression" && node.argument.operator === "-" && !isNumeric(node.argument.argument)) {
                    const recommendation = `Number(${sourceCode.getText(node.argument.argument)})`;

                    report(node, recommendation, false);
                }
            },

            // Use `:exit` to prevent double reporting
            "BinaryExpression:exit"(node) {
                let operatorAllowed;

                // 1 * foo
                operatorAllowed = options.allow.includes("*");
                const nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && !isMultiplyByFractionOfOne(node, sourceCode) &&
                    getNonNumericOperand(node);

                if (nonNumericOperand) {
                    const recommendation = `Number(${sourceCode.getText(nonNumericOperand)})`;

                    report(node, recommendation, true);
                }

                // foo - 0
                operatorAllowed = options.allow.includes("-");
                if (!operatorAllowed && options.number && node.operator === "-" && node.right.type === "Literal" && node.right.value === 0 && !isNumeric(node.left)) {
                    const recommendation = `Number(${sourceCode.getText(node.left)})`;