endo
endo copied to clipboard
patterns: Constructing a pattern should also create a static type
What is the Problem Being Solved?
Independently constructing runtime patterns with M matcher methods and defining static types with @typedef is cumbersome and error-prone, leading us to implement manual validation even when M would be useful (cf. https://github.com/Agoric/agoric-sdk/pull/9169#discussion_r1690588997). It should instead be possible to extract static types from patterns, e.g.
import { mustMatch } from '@endo/patterns';
const BundleShape = M.or(…);
/**
* @param {TypeFromPattern<typeof BundleShape>} bundle
*/
const evaluateBundle = bundle => {
mustMatch(bundle, BundleShape);
const { moduleFormat } = bundle;
…
};
evaluateBundle({}); // static error
Description of the Design
Annotate Matcher functions to return annotated values, and define a utility type for reading such annotations into types.
Security Considerations
None AFAIK
Scaling Considerations
None AFAIK
Test Plan
We should take examples from existing endo and agoric-sdk code.
Compatibility Considerations
None AFAIK
Upgrade Considerations
Nothing out of the ordinary, just the usual caveat that functionality is not incorporated into mainnet vats until they are upgraded.
A successful experiment that leverages const annotation for raw primitives: TypeScript Playground
I'm near the current limits of my knowledge, but this looks very promising as a step beyond even https://github.com/Agoric/agoric-sdk/blob/master/packages/internal/src/types.d.ts#L75-L96 .
And a version with recursive types (which must be actual TypeScript AFAIK) for recognizing e.g. { version: /** @type {const} */ (1), contents: M.string() } as a Pattern without the need for a wrapping call: TypeScript Playground