src/content/docs/linter/rules/use-nullish-coalescing.mdx
import { Tabs, TabItem } from '@astrojs/starlight/components';
<Tabs> <TabItem label="JavaScript (and super languages)" icon="seti:javascript"> :::caution This rule is part of the [nursery](/linter/#nursery) group. This means that it is experimental and the behavior can change at any time. ::: :::note This rule belongs to the types domain. This means that its activation will activate the Biome Scanner to scan the files of your project, and enable the type inference engine. Read more about it in the [documentation page](/linter/domains#types) ::: ## Summary - Rule available since: `v2.4.5` - Diagnostic Category: [`lint/nursery/useNullishCoalescing`](/reference/diagnostics#diagnostic-category) - This rule has a [**safe**](/linter/#safe-fixes) fix. - The default severity of this rule is [**information**](/reference/diagnostics#information). - This rule belongs to the following domains: - [`types`](/linter/domains#types) - Sources: - Inspired from [`@typescript-eslint/prefer-nullish-coalescing`](https://typescript-eslint.io/rules/prefer-nullish-coalescing){
"linter": {
"rules": {
"nursery": {
"useNullishCoalescing": "error"
}
}
}
}
Enforce using the nullish coalescing operator (??) instead of logical or (||).
The ?? operator only checks for null and undefined, while || checks
for any falsy value including 0, '', and false. This can prevent bugs
where legitimate falsy values are incorrectly treated as missing.
For || expressions, this rule triggers when the left operand is possibly
nullish (contains null or undefined in its type). A safe fix is only
offered when type analysis confirms the left operand can only be truthy or
nullish (not other falsy values like 0 or '').
For ||= assignment expressions, the same logic applies: a ||= b is
flagged when a is possibly nullish and can be rewritten as a ??= b.
By default, || expressions in conditional test positions (if/while/for/ternary)
are ignored, as the falsy-checking behavior is often intentional there. This can
be disabled with the ignoreConditionalTests option.
declare const maybeString: string | null;
const value = maybeString || 'default'; // should use ??
declare const maybeNumber: number | undefined;
const value = maybeNumber || 0; // should use ??
declare let x: string | null;
x ||= 'default'; // should use ??=
// Already using ??
declare const maybeString: string | null;
const value = maybeString ?? 'default';
// Type is not nullish - no null or undefined in union
declare const definiteString: string;
const value = definiteString || 'fallback';
// In conditional test position (ignored by default)
declare const cond: string | null;
if (cond || 'fallback') {
console.log('in if');
}
// Already using ??=
declare let y: string | null;
y ??= 'default';