Skip to content

Commit 7fa209f

Browse files
Add status property to the result (#9)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent 180058f commit 7fa209f

File tree

5 files changed

+79
-27
lines changed

5 files changed

+79
-27
lines changed

index.d.ts

+23-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
export interface PromiseFulfilledResult<ValueType> {
2+
status: 'fulfilled';
3+
value: ValueType;
24
isFulfilled: true;
35
isRejected: false;
4-
value: ValueType;
56
}
67

78
export interface PromiseRejectedResult {
9+
status: 'rejected';
10+
reason: unknown;
811
isFulfilled: false;
912
isRejected: true;
10-
reason: unknown;
1113
}
1214

1315
export type PromiseResult<ValueType> =
@@ -38,19 +40,22 @@ console.log(results);
3840
/*
3941
[
4042
{
41-
isFulfilled: true,
42-
isRejected: false,
43+
status: 'fulfilled',
4344
value: '🦄'
45+
isFulfilled: true,
46+
isRejected: false
4447
},
4548
{
46-
isFulfilled: false,
47-
isRejected: true,
49+
status: 'rejected',
4850
reason: [Error: 👹]
51+
isFulfilled: false,
52+
isRejected: true
4953
},
5054
{
51-
isFulfilled: true,
52-
isRejected: false,
55+
status: 'fulfilled',
5356
value: '🐴'
57+
isFulfilled: true,
58+
isRejected: false
5459
}
5560
]
5661
*\/
@@ -67,3 +72,13 @@ console.log(resolvedString);
6772
export default function pReflect<ValueType>(promise: PromiseLike<ValueType>): Promise<
6873
PromiseResult<ValueType>
6974
>;
75+
76+
/**
77+
Narrows a variable of type `PromiseResult` to type `PromiseFulfilledResult` if the variable has the property `value`, otherwise narrows it to the `PromiseRejectedResult` type.
78+
*/
79+
export function isFulfilled<T>(promiseResult: PromiseResult<T>): promiseResult is PromiseFulfilledResult<T>;
80+
81+
/**
82+
Narrows a variable of type `PromiseResult` to type `PromiseRejectedResult` if the variable has the property `reason`, otherwise narrows it to the `PromiseFulfilledResult` type.
83+
*/
84+
export function isRejected<T>(promiseResult: PromiseResult<T>): promiseResult is PromiseRejectedResult;

index.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,25 @@ export default async function pReflect(promise) {
33
const value = await promise;
44

55
return {
6+
status: 'fulfilled',
7+
value,
68
isFulfilled: true,
7-
isRejected: false,
8-
value
9+
isRejected: false
910
};
1011
} catch (error) {
1112
return {
13+
status: 'rejected',
14+
reason: error,
1215
isFulfilled: false,
13-
isRejected: true,
14-
reason: error
16+
isRejected: true
1517
};
1618
}
1719
}
20+
21+
export function isFulfilled(promiseResult) {
22+
return 'value' in promiseResult;
23+
}
24+
25+
export function isRejected(promiseResult) {
26+
return 'reason' in promiseResult;
27+
}

index.test-d.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import {expectType} from 'tsd';
2-
import pReflect from './index.js';
2+
import pReflect, {isFulfilled} from './index.js';
33

44
const result = await pReflect(Promise.resolve('foo'));
55

6-
if (result.isFulfilled) {
6+
if (isFulfilled(result)) {
7+
expectType<'fulfilled'>(result.status);
8+
expectType<string>(result.value);
79
expectType<true>(result.isFulfilled);
810
expectType<false>(result.isRejected);
9-
expectType<string>(result.value);
1011
} else {
12+
expectType<'rejected'>(result.status);
13+
expectType<unknown>(result.reason);
1114
expectType<false>(result.isFulfilled);
1215
expectType<true>(result.isRejected);
13-
expectType<unknown>(result.reason);
1416
}

readme.md

+30-7
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,22 @@ console.log(results);
2929
/*
3030
[
3131
{
32-
isFulfilled: true,
33-
isRejected: false,
32+
status: 'fulfilled',
3433
value: '🦄'
34+
isFulfilled: true,
35+
isRejected: false
3536
},
3637
{
37-
isFulfilled: false,
38-
isRejected: true,
38+
status: 'rejected',
3939
reason: [Error: 👹]
40+
isFulfilled: false,
41+
isRejected: true
4042
},
4143
{
42-
isFulfilled: true,
43-
isRejected: false,
44+
status: 'fulfilled',
4445
value: '🐴'
46+
isFulfilled: true,
47+
isRejected: false
4548
}
4649
]
4750
*/
@@ -65,16 +68,36 @@ Returns a `Promise<Object>`.
6568

6669
The object has the following properties:
6770

71+
- `status` *(`'fulfilled'` or `'rejected'`, depending on how the promise resolved)*
72+
- `value` or `reason` *(Depending on whether the promise fulfilled or rejected)*
6873
- `isFulfilled`
6974
- `isRejected`
70-
- `value` or `reason` *(Depending on whether the promise fulfilled or rejected)*
7175

7276
#### promise
7377

7478
Type: `Promise`
7579

7680
A promise to reflect upon.
7781

82+
### isFulfilled(object)
83+
84+
This is a type guard for TypeScript users.
85+
86+
Returns `true` if the object has the property `value`, `false` otherwise.
87+
88+
This is useful since `await pReflect(promise)` always returns a `PromiseResult`. This function can be used to determine whether `PromiseResult` is `PromiseFulfilledResult` or `PromiseRejectedResult`.
89+
90+
This is a workaround for [microsoft/TypeScript#32399](https://github.com/microsoft/TypeScript/issues/32399)
91+
- reference documentation [Using type predicates](https://www.typescriptlang.org/docs/handbook/2/narrowing.html)
92+
93+
### isRejected(object)
94+
95+
This is a type guard for TypeScript users.
96+
97+
Returns `true` if the object has the property `reason`, `false` otherwise.
98+
99+
This is useful since `await pReflect(promise)` always returns a `PromiseResult`. This function can be used to determine whether `PromiseResult` is `PromiseRejectedResult` or `PromiseFulfilledResult`.
100+
78101
## Related
79102

80103
- [p-settle](https://github.com/sindresorhus/p-settle) - Settle promises concurrently and get their fulfillment value or rejection reason

test.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@ test('main', async t => {
77
t.deepEqual(
88
await pReflect(Promise.resolve(fixture)),
99
{
10+
status: 'fulfilled',
11+
value: fixture,
1012
isFulfilled: true,
11-
isRejected: false,
12-
value: fixture
13+
isRejected: false
1314
}
1415
);
1516

1617
t.deepEqual(
1718
await pReflect(Promise.reject(fixture)),
1819
{
20+
status: 'rejected',
21+
reason: fixture,
1922
isFulfilled: false,
20-
isRejected: true,
21-
reason: fixture
23+
isRejected: true
2224
}
2325
);
2426
});

0 commit comments

Comments
 (0)