跳至主要内容

优先使用空值合并运算符

强制使用空值合并运算符而不是逻辑赋值或链式调用。

💡

此规则报告的一些问题可以通过编辑器手动修复 建议

💭

此规则需要 类型信息 才能运行。

?? 空值合并运行时运算符允许在处理 nullundefined 时提供默认值。由于空值合并运算符在原始值为 nullundefined 时合并,因此它比依赖逻辑或运算符链 || 安全得多,后者会对任何假值进行合并。

此规则报告您可能考虑替换的情况

  • || 运算符为 ??
  • ||= 运算符为 ??=
注意

如果未启用 strictNullChecks,此规则将无法按预期工作。

.eslintrc.cjs
module.exports = {
"rules": {
"@typescript-eslint/prefer-nullish-coalescing": "error"
}
};

在游乐场中尝试此规则 ↗

选项

此规则接受以下选项

type Options = [
{
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing?: boolean;
ignoreConditionalTests?: boolean;
ignoreMixedLogicalExpressions?: boolean;
ignorePrimitives?:
| {
bigint?: boolean;
boolean?: boolean;
number?: boolean;
string?: boolean;
[k: string]: unknown;
}
| true;
ignoreTernaryTests?: boolean;
},
];

const defaultOptions: Options = [
{
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
ignoreConditionalTests: false,
ignoreTernaryTests: false,
ignoreMixedLogicalExpressions: false,
ignorePrimitives: {
bigint: false,
boolean: false,
number: false,
string: false,
},
},
];

ignoreTernaryTests

将此选项设置为 true 将导致规则忽略任何可以使用空值合并运算符简化的三元表达式。默认情况下,此选项设置为 false

ignoreTernaryTests: false 的不正确代码,以及 ignoreTernaryTests: true 的正确代码

const foo: any = 'bar';
foo !== undefined && foo !== null ? foo : 'a string';
foo === undefined || foo === null ? 'a string' : foo;
foo == undefined ? 'a string' : foo;
foo == null ? 'a string' : foo;

const foo: string | undefined = 'bar';
foo !== undefined ? foo : 'a string';
foo === undefined ? 'a string' : foo;

const foo: string | null = 'bar';
foo !== null ? foo : 'a string';
foo === null ? 'a string' : foo;
在游乐场中打开

ignoreTernaryTests: false 的正确代码

const foo: any = 'bar';
foo ?? 'a string';
foo ?? 'a string';
foo ?? 'a string';
foo ?? 'a string';

const foo: string | undefined = 'bar';
foo ?? 'a string';
foo ?? 'a string';

const foo: string | null = 'bar';
foo ?? 'a string';
foo ?? 'a string';
在游乐场中打开

ignoreConditionalTests

将此选项设置为 true 将导致规则忽略位于条件测试中的任何情况。默认情况下,此选项设置为 false

通常,条件测试中的表达式有意使用逻辑或运算符的假值穿透行为,这意味着将运算符修复为空值合并运算符可能会导致错误。

如果您想强制执行更严格的条件测试,您应该考虑使用 strict-boolean-expressions 规则。

ignoreConditionalTests: false 的不正确代码,以及 ignoreConditionalTests: true 的正确代码

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

if (a || b) {
}
if ((a ||= b)) {
}
while (a || b) {}
while ((a ||= b)) {}
do {} while (a || b);
for (let i = 0; a || b; i += 1) {}
a || b ? true : false;
在游乐场中打开

ignoreConditionalTests: false 的正确代码

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

if (a ?? b) {
}
if ((a ??= b)) {
}
while (a ?? b) {}
while ((a ??= b)) {}
do {} while (a ?? b);
for (let i = 0; a ?? b; i += 1) {}
a ?? b ? true : false;
在游乐场中打开

ignoreMixedLogicalExpressions

将此选项设置为 true 将导致规则忽略任何作为混合逻辑表达式(带有 &&)一部分的逻辑或表达式。默认情况下,此选项设置为 false

通常,混合逻辑表达式中的表达式有意使用逻辑或运算符的假值穿透行为,这意味着将运算符修复为空值合并运算符可能会导致错误。

如果您想强制执行更严格的条件测试,您应该考虑使用 strict-boolean-expressions 规则。

ignoreMixedLogicalExpressions: false 的错误代码,以及 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;
(a && b) || c || d;
a || (b && c) || d;
a || (b && c && d);
在游乐场中打开

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;
(a && b) ?? c ?? d;
a ?? (b && c) ?? d;
a ?? (b && c && d);
在游乐场中打开

注意: 此特定情况的错误将作为建议(见下文)呈现,而不是修复。这是因为在混合逻辑表达式中自动将 || 转换为 ?? 并不总是安全的,因为我们无法确定运算符的预期优先级。请注意,根据设计,?? 在与 &&|| 在同一表达式中使用时需要括号。

ignorePrimitives

如果您想忽略包含某些可以为假值的原始类型操作数的表达式,则可以传递一个对象,该对象包含每个原始类型的布尔值

  • string: true,忽略 nullundefinedstring 的联合(默认:false)。
  • number: true,忽略 nullundefinednumber 的联合(默认:false)。
  • bigint: true,忽略 nullundefinedbigint 的联合(默认:false)。
  • boolean: true,忽略 nullundefinedboolean 的联合(默认:false)。

ignorePrimitives: { string: false } 的错误代码,以及 ignorePrimitives: { string: true } 的正确代码

const foo: string | undefined = 'bar';
foo || 'a string';
在游乐场中打开

ignorePrimitives: { string: false }ignorePrimitives: { string: true } 的正确代码

const foo: string | undefined = 'bar';
foo ?? 'a string';
在游乐场中打开

此外,如果您想忽略所有原始类型,可以设置 ignorePrimitives: true。它等效于 ignorePrimitives: { string: true, number: true, bigint: true, boolean: true }

allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing

如果此选项设置为 false,则该规则将对每个 tsconfig.json 文件(其 strictNullChecks 编译器选项(或 strict)未设置为 true)报错。

如果没有 strictNullChecks,TypeScript 基本上会从类型中删除 undefinednull。这意味着当此规则检查变量的类型时,它将无法判断该变量可能是 nullundefined,这实际上使此规则毫无用处。

您应该使用strictNullChecks来确保代码库的完整类型安全。

如果由于某种原因您无法启用strictNullChecks,但仍想使用此规则 - 您可以使用此选项来允许它 - 但请注意,如果编译器选项关闭,此规则的行为是未定义的。如果您使用此选项,我们将不接受错误报告。

何时不使用它

如果您没有使用 TypeScript 3.7(或更高版本),则无法使用此规则,因为该运算符不受支持。

进一步阅读


类型检查的 lint 规则比传统的 lint 规则更强大,但也需要配置类型检查的 lint。如果您在启用类型检查规则后遇到性能下降,请参阅性能故障排除

资源