禁止錯誤使用承諾
禁止在未設計為處理的 Promise 中使用承諾。
延伸 “plugin:@typescript-eslint/recommended-type-checked"
in an ESLint configuration enables this rule.
This rule requires type information to run.
本規則禁止在 TypeScript 編譯器允許但未正確處理的 if 敘述等邏輯位置提供 Promise。這些情況通常是由於缺少 await
關鍵字或僅是因為對非同步函式的處理/等待方式有誤解造成。
module.exports = {
"rules": {
"@typescript-eslint/no-misused-promises": "error"
}
};
在遊樂場中嘗試這個規則 ↗
選項
此規則接受下列選項
type Options = [
{
checksConditionals?: boolean;
checksSpreads?: boolean;
checksVoidReturn?:
| {
arguments?: boolean;
attributes?: boolean;
properties?: boolean;
returns?: boolean;
variables?: boolean;
}
| boolean;
},
];
const defaultOptions: Options = [
{ checksConditionals: true, checksVoidReturn: true, checksSpreads: true },
];
checksConditionals
如果您不想要檢查條件式,可以使用 "checksConditionals": false
設定規則。
{
"@typescript-eslint/no-misused-promises": [
"error",
{
"checksConditionals": false
}
]
}
這樣可以防止規則檢查類似 if (somePromise)
的程式碼。
此規則 checksConditionals: true
的程式碼範例
範例
- ❌ 錯誤
- ✅ 正確
const promise = Promise.resolve('value');
if (promise) {
// Do something
}
const val = promise ? 123 : 456;
while (promise) {
// Do something
}
在遊樂場中開啟const promise = Promise.resolve('value');
// Always `await` the Promise in a conditional
if (await promise) {
// Do something
}
const val = (await promise) ? 123 : 456;
while (await promise) {
// Do something
}
在遊樂場中開啟checksVoidReturn
同樣地,如果您不想要檢查預期為 void 回傳值、但卻回傳承諾的函式,設定會類似這樣
{
"@typescript-eslint/no-misused-promises": [
"error",
{
"checksVoidReturn": false
}
]
}
透過提供用於停用特定檢查的物件,可以停用 checksVoidReturn
選項的部分選擇性項目。支援下列選項
arguments
:停用檢查以引數傳遞、而參數類型預期會傳回void
的非同步函式attributes
:停用檢查以 JSX 屬性傳遞、而預期會傳回void
的非同步函式properties
:停用檢查以物件屬性傳遞、而預期會傳回void
的非同步函式returns
:停用檢查以函式回傳值傳遞、而預期會傳回void
的非同步函式variables
:停用檢查以變數使用的非同步函式、而預期會傳回void
的非同步函式
例如,如果您不介意傳遞 () => Promise<void>
給 () => void
參數或 JSX 屬性,會產生浮動未處理承諾
{
"@typescript-eslint/no-misused-promises": [
"error",
{
"checksVoidReturn": {
"arguments": false,
"attributes": false
}
}
]
}
此規則 checksVoidReturn: true
的程式碼範例
- ❌ 錯誤
- ✅ 正確
[1, 2, 3].forEach(async value => {
await fetch(`/${value}`);
});
new Promise<void>(async (resolve, reject) => {
await fetch('/');
resolve();
});
document.addEventListener('click', async () => {
console.log('synchronous call');
await fetch('/');
console.log('synchronous call');
});
在遊樂場中開啟// for-of puts `await` in outer context
for (const value of [1, 2, 3]) {
await doSomething(value);
}
// If outer context is not `async`, handle error explicitly
Promise.all(
[1, 2, 3].map(async value => {
await doSomething(value);
}),
).catch(handleError);
// Use an async IIFE wrapper
new Promise((resolve, reject) => {
// combine with `void` keyword to tell `no-floating-promises` rule to ignore unhandled rejection
void (async () => {
await doSomething();
resolve();
})();
});
// Name the async wrapper to call it later
document.addEventListener('click', () => {
const handler = async () => {
await doSomething();
otherSynchronousCall();
};
try {
synchronousCall();
} catch (err) {
handleSpecificError(err);
}
handler().catch(handleError);
});
在遊樂場中開啟checksSpreads
如果您不想要檢查物件擴散,可以新增這個設定
{
"@typescript-eslint/no-misused-promises": [
"error",
{
"checksSpreads": false
}
]
}
此規則 checksSpreads: true
的程式碼範例
- ❌ 錯誤
- ✅ 正確
const getData = () => fetch('/');
console.log({ foo: 42, ...getData() });
const awaitData = async () => {
await fetch('/');
};
console.log({ foo: 42, ...awaitData() });
在遊樂場中開啟const getData = () => fetch('/');
console.log({ foo: 42, ...(await getData()) });
const awaitData = async () => {
await fetch('/');
};
console.log({ foo: 42, ...(await awaitData()) });
在遊樂場中開啟不適用的情況
這個規則可能難以在設定很多使用不當 Promise 的大型現有專案中啟用。或者,若您不擔心浮動或使用不當的 Promise 導致的崩潰 - 例如您已註冊全域性未處理的 Promise 處理常式 - 那麼在某些情況中不使用這個規則可能是安全的。您可以考慮對特定情況使用 ESLint disable 註解,而非完全停用這個規則。
延伸閱讀
相關性
經過類型檢查的 lint 規則比傳統的 lint 規則更強大,但同時也需要設定 經過類型檢查的 linting。若您在啟用經過類型檢查的規則後遇到效能下降問題,請參閱 效能疑難排解。