oxc-project/oxc · warning

Unexpected implicit coercion to number

Error message

Unexpected implicit coercion to number

What it means

The number-kind diagnostic of oxlint's no-implicit-coercion rule. It flags unary plus +value and multiplication by one (value * 1, 1 * value), the shorthand coercions to number, and recommends the explicit Number(value) call. Options control whether number coercion is checked and which shorthand forms are allowed.

Source

Thrown at crates/oxc_linter/src/rules/eslint/no_implicit_coercion.rs:23

use oxc_str::CompactStr;
use oxc_syntax::operator::{AssignmentOperator, BinaryOperator, UnaryOperator};
use schemars::JsonSchema;
use serde::Deserialize;

use crate::{
    AstNode,
    context::LintContext,
    rule::{DefaultRuleConfig, Rule},
};

fn boolean_coercion_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Unexpected implicit coercion to boolean")
        .with_help("Use `Boolean(value)` instead")
        .with_label(span)
}

fn number_coercion_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Unexpected implicit coercion to number")
        .with_help("Use `Number(value)` instead")
        .with_label(span)
}

fn string_coercion_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Unexpected implicit coercion to string")
        .with_help("Use `String(value)` instead")
        .with_label(span)
}

/// Type of implicit coercion being detected
#[derive(Clone, Copy)]
enum CoercionKind {
    Boolean,
    Number,
    String,
}

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Use Number(value) for straight conversion.
  2. Use Number.parseInt(value, 10) or Number.parseFloat when parsing strings (usually the real intent).
  3. Allow the + shorthand via the rule's allow option if it is team style.
  4. Turn off number checks in the rule options.

Example fix

// before
const count = +inputEl.value;

// after
const count = Number.parseInt(inputEl.value, 10);
Defensive patterns

Strategy: type-guard

Validate before calling

const plusCast = /[=(,[]\s*\+\s*[A-Za-z_(]/.test(source);

Type guard

const asNum = (v: unknown): number => (typeof v === 'number' ? v : Number(v));

Prevention

When it happens

Trigger: const n = +input.value;; total = raw * 1;; 1 * qty used to force numeric strings into numbers; +el.dataset.count passed around as a number.

Common situations: Parsing DOM inputs, dataset attributes, and query-string params where unary plus is the habitual trick; old code-golf snippets copied from forums; a strictness sweep turning the rule on mid-project.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/1ef53338b06ce4ad. Report an issue: GitHub.