no-misused-promises
禁止在未设计为处理 Promise 的地方使用 Promise。
在 "plugin:@typescript-eslint/recommended-type-checked"
中扩展 ESLint 配置 将启用此规则。
此规则需要 类型信息 才能运行。
此规则禁止在 if 语句等逻辑位置提供 Promise,即使 TypeScript 编译器允许这样做,但它们没有得到正确处理。这些情况通常是由于缺少 await
关键字或仅仅是对异步函数处理/等待方式的误解造成的。
no-misused-promises
仅检测将 Promise 提供给不正确的逻辑位置的代码。有关检测未处理的 Promise语句,请参见 no-floating-promises
。
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
同样,如果您不想检查返回 Promise 的函数,而这些函数的预期返回值为 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 属性会导致浮动未处理的 Promise
{
"@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 禁用注释 针对这些特定情况,而不是完全禁用此规则。
进一步阅读
相关
类型检查的 lint 规则比传统的 lint 规则更强大,但也需要配置 类型检查的 lint。如果您在启用类型检查规则后遇到性能下降,请参阅 性能故障排除。