Back to Biomejs

useNullishCoalescing

src/content/docs/linter/rules/use-nullish-coalescing.mdx

latest3.3 KB
Original Source

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)

How to configure

json
{
	"linter": {
		"rules": {
			"nursery": {
				"useNullishCoalescing": "error"
			}
		}
	}
}

Description

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.

Examples

Invalid

ts
declare const maybeString: string | null;
const value = maybeString || 'default'; // should use ??
ts
declare const maybeNumber: number | undefined;
const value = maybeNumber || 0; // should use ??
ts
declare let x: string | null;
x ||= 'default'; // should use ??=

Valid

ts
// Already using ??
declare const maybeString: string | null;
const value = maybeString ?? 'default';
ts
// Type is not nullish - no null or undefined in union
declare const definiteString: string;
const value = definiteString || 'fallback';
ts
// In conditional test position (ignored by default)
declare const cond: string | null;
if (cond || 'fallback') {
  console.log('in if');
}
ts
// Already using ??=
declare let y: string | null;
y ??= 'default';
</TabItem> </Tabs>