{"record":{"id":"620bb7c4ac447b9a","repo":"oxc-project/oxc","slug":"unexpected-implicit-coercion-to-string","errorCode":null,"errorMessage":"Unexpected implicit coercion to string","messagePattern":"Unexpected implicit coercion to string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/no_implicit_coercion.rs","lineNumber":29,"sourceCode":"    AstNode,\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn boolean_coercion_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected implicit coercion to boolean\")\n        .with_help(\"Use `Boolean(value)` instead\")\n        .with_label(span)\n}\n\nfn number_coercion_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected implicit coercion to number\")\n        .with_help(\"Use `Number(value)` instead\")\n        .with_label(span)\n}\n\nfn string_coercion_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected implicit coercion to string\")\n        .with_help(\"Use `String(value)` instead\")\n        .with_label(span)\n}\n\n/// Type of implicit coercion being detected\n#[derive(Clone, Copy)]\nenum CoercionKind {\n    Boolean,\n    Number,\n    String,\n}\n\n/// Reports an implicit coercion with an auto-fix suggestion\nfn report_coercion(ctx: &LintContext, span: Span, kind: CoercionKind, operand: &str) {\n    let (diagnostic, wrapper) = match kind {\n        CoercionKind::Boolean => (boolean_coercion_diagnostic(span), \"Boolean\"),\n        CoercionKind::Number => (number_coercion_diagnostic(span), \"Number\"),\n        CoercionKind::String => (string_coercion_diagnostic(span), \"String\"),","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_implicit_coercion.rs#L11-L47","documentation":"The string-kind diagnostic of oxlint's no-implicit-coercion rule. It flags template literals whose only content is a single interpolation (`${value}`), string concatenation like value + '' or '' + value, and value += ''. The rule wants String(value) so the conversion is explicit; templates that contain literal text around interpolations are fine.","triggerScenarios":"const key = `${user.id}`;; '' + flags; text += ''; concatenating x + '' to build object keys or log lines.","commonSituations":"Building object keys from ids; stringifying numbers or symbols for logging; the '' + x trick carried over from older snippets.","solutions":["Use String(value) for the conversion.","Keep template literals only when they contain literal text around the interpolation.","Disable string checks in the rule options if template style is intentional."],"exampleFix":"// before\nconst key = `${user.id}`;\n\n// after\nconst key = String(user.id);","handlingStrategy":"type-guard","validationCode":"const strCast = /(?:`\\$\\{[^}]+\\}`|\\+\\s*''|''\\s*\\+)/.test(source);","typeGuard":"const asStr = (v: unknown): string => (typeof v === 'string' ? v : String(v));","tryCatchPattern":null,"preventionTips":["Use String(x) for explicit string conversion.","Build object keys with String(x) instead of `${x}` alone.","Reserve template literals for strings with literal text around interpolations."],"tags":["eslint","oxlint","lint","coercion","string"],"backgroundTag":"implicit-string-coercion","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}