{"record":{"id":"379677f00f480452","repo":"oxc-project/oxc","slug":"type-can-be-trivially-inferred-from-the-initialize","errorCode":null,"errorMessage":"Type can be trivially inferred from the initializer","messagePattern":"Type can be trivially inferred from the initializer","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/typescript/no_inferrable_types.rs","lineNumber":22,"sourceCode":"    ast::{\n        ChainElement, Expression, FormalParameter, TSLiteral, TSType, TSTypeAnnotation, TSTypeName,\n        UnaryOperator,\n    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\nuse schemars::JsonSchema;\nuse serde::Deserialize;\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn no_inferrable_types_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Type can be trivially inferred from the initializer\")\n        .with_help(\"Remove the type annotation\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct NoInferrableTypes {\n    /// When set to `true`, ignores type annotations on function parameters.\n    ignore_parameters: bool,\n    /// When set to `true`, ignores type annotations on class properties.\n    ignore_properties: bool,\n}\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow explicit type declarations for variables or parameters initialized to a number, string, or boolean.\n    ///","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/typescript/no_inferrable_types.rs#L4-L40","documentation":"Diagnostic from oxlint's port of @typescript-eslint/no-inferrable-types. It reports type annotations that TypeScript infers trivially from the initializer — `const n: number = 5`, `let flag: boolean = true`, regex, string literal initializers, defaulted parameters `function f(a: number = 1)`, class properties. The annotation is redundant noise that can even mask a type change (initializer changes type while annotation keeps the declared type). Options `ignoreParameters` and `ignoreProperties` exempt params and class fields.","triggerScenarios":"Variable/property declarations and defaulted parameters whose annotation is one of the trivially-inferable kinds while an initializer literal is present; per the config, parameter annotations are exempt when ignoreParameters=true and class-property annotations when ignoreProperties=true.","commonSituations":"Developers from Java/C# backgrounds annotating everything; IDE auto-import/quick-fix inserting annotations; explicit-type style guides; defaulted function parameters annotated `a: number = 0`.","solutions":["Delete the annotation and let inference work: `const n = 5`.","For defaulted params you want to keep strict, either annotate a wider type (`function f(a: number | undefined = 1)`) or enable ignoreParameters.","Set `ignoreProperties`/`ignoreParameters` if class fields/params are your accepted style.","Disable the rule repo-wide if your team mandates explicit types."],"exampleFix":"// before\nconst port: number = 8080;\nlet verbose: boolean = false;\nclass Config { timeout: number = 30; }\n\n// after\nconst port = 8080;\nlet verbose = false;\nclass Config { timeout = 30; }","handlingStrategy":"validation","validationCode":"oxlint --ts-plugin src/ # no-inferrable-types; add ignoreParameters/ignoreProperties if needed","typeGuard":"// when you DO need a wider declared type than the initializer, say it explicitly:\nlet status: 'idle' | 'busy' = 'idle'; // union is not trivially inferrable → rule stays quiet","tryCatchPattern":null,"preventionTips":["Annotate only what inference cannot determine (unions, wider interfaces, function boundaries).","If house style demands annotations on params/class fields, flip ignoreParameters/ignoreProperties rather than disabling the rule.","Let `const x = 5;` carry the literal type — it is usually what you want."],"tags":["typescript","type-inference","redundant-code","oxlint","lint","style"],"backgroundTag":"redundant-type-annotation","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}