import { create, RuntypeBase, Codec, Static } from '../runtype'; import show from '../show'; export interface Lazy> extends Codec> { readonly tag: 'lazy'; readonly underlying: () => TUnderlying; } export function lazyValue(fn: () => T) { let value: T; return () => { return value || (value = fn()); }; } /** * Construct a possibly-recursive Runtype. */ export function Lazy>( delayed: () => TUnderlying, ): Lazy { const underlying = lazyValue(delayed); return create>( 'lazy', { p: (value, _innerValidate, innerValidateToPlaceholder) => innerValidateToPlaceholder(underlying(), value) as any, u: underlying, }, { underlying, show(needsParens) { return show(underlying(), needsParens); }, }, ); }