Skip to content

Commit

Permalink
Merge pull request #6976 from Agoric/ta/fix-deeplyAwaited
Browse files Browse the repository at this point in the history
improve types of fulfillment helpers
  • Loading branch information
mergify[bot] authored Feb 12, 2023
2 parents 93e8bb9 + 2683f47 commit adc0836
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
2 changes: 1 addition & 1 deletion packages/inter-protocol/src/collect.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { fromEntries, keys, values } = Object;
/** @type { <X, Y>(xs: X[], ys: Y[]) => [X, Y][]} */
export const zip = (xs, ys) => harden(xs.map((x, i) => [x, ys[+i]]));

/** @type { <K extends string, V>(obj: Record<K, ERef<V>>) => Promise<Record<K, V>> } */
/** @type { <T extends Record<string, ERef<any>>>(obj: T) => Promise<{ [K in keyof T]: Awaited<T[K]>}> } */
export const allValues = async obj => {
const resolved = await Promise.all(values(obj));
// @ts-expect-error cast
Expand Down
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 adc0836

Please sign in to comment.