Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions docs/rules/no-unsafe-promise-all-settled-values.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# no-unsafe-promise-all-settled-values

📝 Disallow reading `.value` from `Promise.allSettled()` results without a fulfilled status guard.

💼 This rule is enabled in the following [configs](https://github.com/sindresorhus/eslint-plugin-unicorn#recommended-config): ✅ `recommended`, ☑️ `unopinionated`.

<!-- end auto-generated rule header -->
<!-- Do not manually modify this header. Run: `npm run fix:eslint-docs` -->

`Promise.allSettled()` returns both fulfilled and rejected result objects. Only fulfilled results have a `.value` property. Reading `.value` without first checking `status === 'fulfilled'` turns rejected results into `undefined`, which can silently drop failures.

This rule reports direct `.map()` extraction from known `Promise.allSettled()` result arrays, including simple `const` aliases. It intentionally keeps a narrow inference boundary: arbitrary aliasing, mutable `let` tracking, custom guard functions without type information, and broad non-`.map()` dataflow are out of scope.

With TypeScript type information, typed predicate filters that narrow entries to `PromiseFulfilledResult<T>` are treated as safe.

## Examples

```js
// ❌
const values = (await Promise.allSettled(promises)).map(result => result.value);

// ✅
const values = (await Promise.allSettled(promises))
.filter(result => result.status === 'fulfilled')
.map(result => result.value);
```

```js
// ❌
const values = Promise.allSettled(promises).then(results => results.map(result => result.value));

// ✅
const values = Promise.allSettled(promises).then(results =>
results.map(result => result.status === 'fulfilled' ? result.value : undefined)
);
```

```ts
// ✅
const isFulfilled = <T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T> => result.status === 'fulfilled';
const values = results.filter(isFulfilled).map(result => result.value);
```
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ export default defineConfig([
| [no-unreadable-object-destructuring](docs/rules/no-unreadable-object-destructuring.md) | Disallow unreadable object destructuring. | ✅ ☑️ | | | |
| [no-unsafe-buffer-conversion](docs/rules/no-unsafe-buffer-conversion.md) | Prevent unsafe use of ArrayBuffer view `.buffer`. | ✅ ☑️ | | 💡 | |
| [no-unsafe-dom-html](docs/rules/no-unsafe-dom-html.md) | Disallow unsafe DOM HTML APIs. | | | | |
| [no-unsafe-promise-all-settled-values](docs/rules/no-unsafe-promise-all-settled-values.md) | Disallow reading `.value` from `Promise.allSettled()` results without a fulfilled status guard. | ✅ ☑️ | | | |
| [no-unsafe-property-key](docs/rules/no-unsafe-property-key.md) | Disallow unsafe values as property keys. | ✅ | | | |
| [no-unsafe-string-replacement](docs/rules/no-unsafe-string-replacement.md) | Disallow non-literal replacement values in `String#replace()` and `String#replaceAll()`. | ✅ | | | |
| [no-unused-array-method-return](docs/rules/no-unused-array-method-return.md) | Disallow ignoring the return value of selected array methods. | ✅ ☑️ | | | |
Expand Down
1 change: 1 addition & 0 deletions rules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export {default as 'no-unreadable-new-expression'} from './no-unreadable-new-exp
export {default as 'no-unreadable-object-destructuring'} from './no-unreadable-object-destructuring.js';
export {default as 'no-unsafe-buffer-conversion'} from './no-unsafe-buffer-conversion.js';
export {default as 'no-unsafe-dom-html'} from './no-unsafe-dom-html.js';
export {default as 'no-unsafe-promise-all-settled-values'} from './no-unsafe-promise-all-settled-values.js';
export {default as 'no-unsafe-property-key'} from './no-unsafe-property-key.js';
export {default as 'no-unsafe-string-replacement'} from './no-unsafe-string-replacement.js';
export {default as 'no-unused-array-method-return'} from './no-unused-array-method-return.js';
Expand Down
Loading
Loading