Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
2 contributors

Users who have contributed to this file

@bradzacher @armano2
149 lines (105 sloc) 4.75 KB

Enforce the usage of the nullish coalescing operator instead of logical chaining (prefer-nullish-coalescing)

TypeScript 3.7 added support for the nullish coalescing operator. This operator allows you to safely cascade a value when dealing with null or undefined.

function myFunc(foo: string | null) {
  return foo ?? 'a string';
}

// is equivalent to

function myFunc(foo: string | null) {
  return foo !== null && foo !== undefined ? foo : 'a string';
}

Because the nullish coalescing operator only coalesces when the original value is null or undefined, it is much safer than relying upon logical OR operator chaining ||; which coalesces on any falsy value:

const emptyString = '';

const nullish1 = emptyString ?? 'unsafe';
const logical1 = emptyString || 'unsafe';

// nullish1 === ''
// logical1 === 'unsafe'

declare const nullString: string | null;

const nullish2 = nullString ?? 'safe';
const logical2 = nullString || 'safe';

// nullish2 === 'safe'
// logical2 === 'safe'

Rule Details

This rule aims enforce the usage of the safer operator.

Options

type Options = [
  {
    ignoreConditionalTests?: boolean;
    ignoreMixedLogicalExpressions?: boolean;
    forceSuggestionFixer?: boolean;
  },
];

const defaultOptions = [
  {
    ignoreConditionalTests: true,
    ignoreMixedLogicalExpressions: true,
    forceSuggestionFixer: false,
  },
];

ignoreConditionalTests

Setting this option to true (the default) will cause the rule to ignore any cases that are located within a conditional test.

Generally expressions within conditional tests intentionally use the falsy fallthrough behavior of the logical or operator, meaning that fixing the operator to the nullish coalesce operator could cause bugs.

If you're looking to enforce stricter conditional tests, you should consider using the strict-boolean-expressions rule.

Incorrect code for ignoreConditionalTests: false, and correct code for ignoreConditionalTests: true:

declare const a: string | null;
declare const b: string | null;

if (a || b) {
}
while (a || b) {}
do {} while (a || b);
for (let i = 0; a || b; i += 1) {}
a || b ? true : false;

Correct code for ignoreConditionalTests: false:

declare const a: string | null;
declare const b: string | null;

if (a ?? b) {
}
while (a ?? b) {}
do {} while (a ?? b);
for (let i = 0; a ?? b; i += 1) {}
a ?? b ? true : false;

ignoreMixedLogicalExpressions

Setting this option to true (the default) will cause the rule to ignore any logical or expressions that are part of a mixed logical expression (with &&).

Generally expressions within mixed logical expressions intentionally use the falsy fallthrough behavior of the logical or operator, meaning that fixing the operator to the nullish coalesce operator could cause bugs.

If you're looking to enforce stricter conditional tests, you should consider using the strict-boolean-expressions rule.

Incorrect code for ignoreMixedLogicalExpressions: false, and correct code for ignoreMixedLogicalExpressions: true:

declare const a: string | null;
declare const b: string | null;
declare const c: string | null;
declare const d: string | null;

a || (b && c);
(a && b) || c || d;
a || (b && c) || d;
a || (b && c && d);

Correct code for ignoreMixedLogicalExpressions: false:

declare const a: string | null;
declare const b: string | null;
declare const c: string | null;
declare const d: string | null;

a ?? (b && c);
(a && b) ?? c ?? d;
a ?? (b && c) ?? d;
a ?? (b && c && d);

NOTE: Errors for this specific case will be presented as suggestions (see below), instead of fixes. This is because it is not always safe to automatically convert || to ?? within a mixed logical expression, as we cannot tell the intended precedence of the operator. Note that by design, ?? requires parentheses when used with && or || in the same expression.

forceSuggestionFixer

Setting this option to true will cause the rule to use ESLint's "suggested fix" mode for all fixes. This option is provided as to aid in transitioning your codebase onto this rule.

Suggestion fixes cannot be automatically applied via the --fix CLI command, but can be manually chosen to be applied one at a time via an IDE or similar. This makes it safe to run autofixers on an existing codebase without worrying about potential runtime behavior changes from this rule's fixer.

When Not To Use It

If you are not using TypeScript 3.7 (or greater), then you will not be able to use this rule, as the operator is not supported.

Further Reading

You can’t perform that action at this time.