{"record":{"id":"5c0de979f92e4e7c","repo":"oxc-project/oxc","slug":"extra-non-null-assertion","errorCode":null,"errorMessage":"extra non-null assertion","messagePattern":"extra non-null assertion","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/typescript/no_extra_non_null_assertion.rs","lineNumber":17,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{ChainElement, Expression, match_member_expression},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\n\nuse crate::{\n    AstNode,\n    ast_util::outermost_paren_parent,\n    context::{ContextHost, LintContext},\n    rule::Rule,\n};\n\nfn no_extra_non_null_assertion_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"extra non-null assertion\")\n        .with_help(\"Remove the redundant non-null assertion operator (`!`).\")\n        .with_note(\"The non-null assertion operator in TypeScript, written as `!`, tells the compiler that an expression is definitely not `null` or `undefined` at that point. Chaining multiple non-null assertions on the same expression does not provide any additional safety and is redundant.\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoExtraNonNullAssertion;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow extra non-null assertions.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// The `!` non-null assertion operator in TypeScript is used to assert that a value's type\n    /// does not include `null` or `undefined`. Using the operator any more than once on a single value\n    /// does nothing.","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/typescript/no_extra_non_null_assertion.rs#L1-L35","documentation":"Oxlint's no-extra-non-null-assertion flags redundant chained non-null assertions. A single `!` already strips null and undefined from the type, so chaining adds nothing; the note at no_extra_non_null_assertion.rs:20-24 explains precisely this. Each extra assertion on top of the first is reported.","triggerScenarios":"`foo!!`, `foo!!.bar`, `(foo!)!`, `foo?.bar!!` - a TSNonNullAssertion whose inner expression is itself a non-null assertion.","commonSituations":"Copy-paste chains, code generation, developers unsure whether one `!` sufficed and adding another to silence the compiler.","solutions":["Delete the extra `!` operators, keeping at most one","If the value may genuinely be null or undefined, use `?.` or an explicit check instead of stacking assertions","Run the linter with --fix in your editor so the redundant operator is stripped as you type"],"exampleFix":"// before\nconst name = user!!.name;\n\n// after\nconst name = user?.name;","handlingStrategy":"validation","validationCode":"npx oxlint --deny-warnings .","typeGuard":"function isDefined<T>(value: T | null | undefined): value is T {\n  return value !== null && value !== undefined;\n}","tryCatchPattern":null,"preventionTips":["Search for `!!` and `!!!` in review diffs; stacked assertions are always suspect","Prefer `?.` over `!` when nullability is possible","Enable the rule in the editor so the redundant `!` is highlighted the moment it is typed"],"tags":["typescript","lint","non-null-assertion","redundant-code"],"backgroundTag":"extra-non-null-assertion","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"}