偏好可選連鎖
強制使用簡潔的可選鏈式表達式,而非鏈式邏輯與運算式、邏輯或非運算式或空物件。
?.
可選鏈式表達式在物件為 null
或 undefined
時提供 undefined
。由於可選鏈式運算子 僅 在屬性值為 null
或 undefined
時才會進行鏈式運算,因此它比依賴邏輯與運算元鏈式運算 &&
安全得多。而 &&
任何真值都會進行鏈式運算。此外,與 &&
真值檢查相比,使用 ?.
可選鏈式運算通常會產生較少的程式碼。
此規則會回報可安全地將 &&
這個運算子替換為 ?.
可選鍊接的情況。
module.exports = {
"rules": {
"@typescript-eslint/prefer-optional-chain": "error"
}
};
在遊樂場試試此規則 ↗
範例
- ❌ 錯誤
- ✅ 正確
foo && foo.a && foo.a.b && foo.a.b.c;
foo && foo['a'] && foo['a'].b && foo['a'].b.c;
foo && foo.a && foo.a.b && foo.a.b.method && foo.a.b.method();
// With empty objects
(((foo || {}).a || {}).b || {}).c;
(((foo || {})['a'] || {}).b || {}).c;
// With negated `or`s
!foo || !foo.bar;
!foo || !foo[bar];
!foo || !foo.bar || !foo.bar.baz || !foo.bar.baz();
// this rule also supports converting chained strict nullish checks:
foo &&
foo.a != null &&
foo.a.b !== null &&
foo.a.b.c != undefined &&
foo.a.b.c.d !== undefined &&
foo.a.b.c.d.e;
在遊樂場開啟foo?.a?.b?.c;
foo?.['a']?.b?.c;
foo?.a?.b?.method?.();
foo?.a?.b?.c?.d?.e;
!foo?.bar;
!foo?.[bar];
!foo?.bar?.baz?.();
在遊樂場開啟選項
此規則可接受以下的選項
type Options = [
{
/** Allow autofixers that will change the return type of the expression. This option is considered unsafe as it may break the build. */
allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing?: boolean;
/** Check operands that are typed as `any` when inspecting "loose boolean" operands. */
checkAny?: boolean;
/** Check operands that are typed as `bigint` when inspecting "loose boolean" operands. */
checkBigInt?: boolean;
/** Check operands that are typed as `boolean` when inspecting "loose boolean" operands. */
checkBoolean?: boolean;
/** Check operands that are typed as `number` when inspecting "loose boolean" operands. */
checkNumber?: boolean;
/** Check operands that are typed as `string` when inspecting "loose boolean" operands. */
checkString?: boolean;
/** Check operands that are typed as `unknown` when inspecting "loose boolean" operands. */
checkUnknown?: boolean;
/** Skip operands that are not typed with `null` and/or `undefined` when inspecting "loose boolean" operands. */
requireNullish?: boolean;
},
];
const defaultOptions: Options = [
{
checkAny: true,
checkUnknown: true,
checkString: true,
checkNumber: true,
checkBoolean: true,
checkBigInt: true,
requireNullish: false,
allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing: false,
},
];
在以下說明的脈絡中,「不嚴謹布林」運算元是不會強制轉換值為布林的運算元。特別的是,un operator(!loose
)或邏輯表達式中的裸值(loose && looser
)的參數。
allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing
當此選項為 true
時,規則會提供自動修改程式,以修正表達式傳回型別變更的情況。例如,對於表達式 !foo || foo.bar
,表達式的傳回型別為 true | T
,然而對於同等的選用鍊接 foo?.bar
,表達式的傳回型別為 undefined | T
。因此將程式碼從邏輯表達式變更為選用鍊接表達式會改變表達式的型別。
在某些情況下,此差異可能會很重要,這就是為什麼這些修改程式被認為不安全的原因,它們可能會導致編譯錯誤!例如,在以下程式碼中
declare const foo: { bar: boolean } | null | undefined;
declare function acceptsBoolean(arg: boolean): void;
// ✅ typechecks succesfully as the expression only returns `boolean`
acceptsBoolean(foo != null && foo.bar);
// ❌ typechecks UNSUCCESSFULLY as the expression returns `boolean | undefined`
acceptsBoolean(foo?.bar);
在遊樂場開啟這種程式碼樣式並不是很常見,這表示將此選項設定為 true
應該對大部分的程式碼庫是安全的。然而,由於此選項本質上不安全,因此我們預設為 false
。我們提供此選項的目的是為了方便,因為它會增加規則所涵蓋的自動修改程式情況。如果您將選項設定為 true
,那麼確保每個修改程式正確且安全,而且不會導致編譯錯誤,就完全是您和您的團隊的責任。
當此選項為 false
時,不安全的案例會提供建議修改程式,而不是提供自動修改程式,這表示您可以使用 IDE 工具手動套用修改程式。
checkAny
當此選項為 true
時,規則會在檢查「不嚴謹布林」運算元時,檢查為 any
型別的運算元。
- 針對 `checkAny: true` 出錯
- 針對 `checkAny: false` 正確
checkUnknown
當此選項為 true
時,規則會在檢查「不嚴謹布林」運算元時,檢查為 unknown
型別的運算元。
- 針對 `checkUnknown: true` 出錯
- 針對 `checkUnknown: false` 正確
checkString
當這個選項為 true
時,規則會在檢查「寬鬆布林值」運算元時,檢查型別為 string
的運算元。
- ❌ 不正確的範例,`checkString: true`
- ✅ 正確的範例,`checkString: false`
checkNumber
當這個選項為 true
時,規則會在檢查「寬鬆布林值」運算元時,檢查型別為 number
的運算元。
- ❌ 不正確的範例,`checkNumber: true`
- ✅ 正確的範例,`checkNumber: false`
checkBoolean
當這個選項為 true
時,規則會在檢查「寬鬆布林值」運算元時,檢查型別為 boolean
的運算元。
這個規則有意的忽略以下的案例
declare const x: false | { a: string };
x && x.a;
!x || x.a;
布林值表達式縮小非 null 的錯誤情況 - 所以將連鎖轉換為 x?.a
會產生型別錯誤。
- ❌ 不正確的範例,`checkBoolean: true`
- ✅ 正確的範例,`checkBoolean: false`
checkBigInt
當這個選項為 true
時,規則會在檢查「寬鬆布林值」運算元時,檢查型別為 bigint
的運算元。
- ❌ 不正確的範例,`checkBigInt: true`
- ✅ 正確的範例,`checkBigInt: false`
requireNullish
當這個選項為 true
時,規則會在檢查「寬鬆布林值」運算元時,略過型別不是 null
和/或 undefined
的運算元。
- ❌ 不正確的範例,`requireNullish: true`
- ✅ 正確的範例,`requireNullish: true`
什麼時候不使用
如果你的專案型別不正確,例如專案正在轉換為 TypeScript 的過程中,或是容易受到 控制流程分析的取捨 的影響,可能會難以針對特別是非型別安全的程式碼區域啟用這條規則。
延伸閱讀
類型檢查之棉絮規則比傳統棉絮規則強大,但也需要設定 類型檢查棉絮。如果你在啟用類型檢查規則後發現效能降低,請參閱 效能疑難排解。