Skip to content

Commit

Permalink
chore(types): improve deeplyFulfilledObject return type
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Feb 12, 2023
1 parent 98c5b62 commit 2683f47
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 6 deletions.
19 changes: 13 additions & 6 deletions packages/internal/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,18 +248,25 @@ export const bindAllMethods = obj =>
);
harden(bindAllMethods);

/**
* @template T
* @typedef {{[KeyType in keyof T]: T[KeyType]} & {}} Simplify
* flatten the type output to improve type hints shown in editors
* https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts
*/

/**
* @typedef {(...args: any[]) => any} Callable
*/

/**
* @template {{}} T
* @typedef {{ [K in keyof T]: DeeplyAwaited<T[K]> }} DeeplyAwaitedObject
* @typedef {{ [K in keyof T]: T[K] extends Callable ? T[K] : DeeplyAwaited<T[K]> }} DeeplyAwaitedObject
*/

/**
* Caveats:
* - doesn't recur within Promise results
* - resulting type has wrapper in its name
*
* @template T
* @typedef {T extends PromiseLike<any> ? Awaited<T> : T extends {} ? DeeplyAwaitedObject<T> : Awaited<T>} DeeplyAwaited
* @typedef {T extends PromiseLike<any> ? Awaited<T> : T extends {} ? Simplify<DeeplyAwaitedObject<T>> : Awaited<T>} DeeplyAwaited
*/

/**
Expand Down
20 changes: 20 additions & 0 deletions packages/internal/test/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import test from 'ava';
import '@endo/init';

import { Far } from '@endo/marshal';
import {
fromUniqueEntries,
objectMap,
Expand All @@ -10,6 +11,7 @@ import {
whileTrue,
untilTrue,
forever,
deeplyFulfilledObject,
} from '../src/utils.js';

test('fromUniqueEntries', t => {
Expand Down Expand Up @@ -57,6 +59,24 @@ test('objectMap', t => {
);
});

test('deeplyFulfilledObject', async t => {
const someFar = Far('somefar', { getAsync: () => Promise.resolve('async') });
const unfulfilled = harden({
obj1: {
obj2a: {
stringP: Promise.resolve('foo'),
},
obj2b: someFar,
},
});
const fulfilled = await deeplyFulfilledObject(unfulfilled);
// JS check that it's a now string
fulfilled.obj1.obj2a.stringP.length;
t.deepEqual(fulfilled, {
obj1: { obj2a: { stringP: 'foo' }, obj2b: someFar },
});
});

test('makeMeasureSeconds', async t => {
const times = [1000.25, 2000.75, NaN];
/** @type {() => number} */
Expand Down

0 comments on commit 2683f47

Please sign in to comment.