import { format } from "util" ; export type Maybe < T > = Option < T > | undefined ; export type Option < T > = T | null ; export type Table < T > = { [ key ] : T ; } ; export interface Class < T > { new ( ... args ) : T ; } export namespace Class { const invalidCast = `Expected "%s" to be an instance of %s. Received %s.` ; export function cast < T > ( constructor , variable , value ) { return ( tryCast ( constructor , value ) || bail ( invalidCast , variable , constructor . name , value ? value . constructor . name : value ) ) ; } export function tryCast < T > ( constructor , value ) { return value instanceof constructor ? value : null ; } } export function assert ( condition , message ? , ... variables ) { return condition ? undefined : bail ( message || "Assertion Failed" , ... variables ) ; } export function bail ( message , ... variables ) { throw new Error ( format ( message , variables ) ) ; } export function expect < T > ( value , message ? , ... variables ) { assert ( value != null , message , ... variables ) ; return value as T ; } export function findMap < T , U > ( items , fn ) { for ( const input of items ) { const output = fn ( input ) ; if ( output != null ) { return output ; } } } export function filterMapValues < T , U > ( items , fn ) { const mapped = { } ; Object . entries ( items ) . forEach ( ( [ key , item ] ) => { const result = fn ( item ) ; if ( result != null ) { mapped [ key ] = result ; } } ) ; return mapped ; } export function warn ( message , ... variables ) { if ( process . env . NODE_ENV !== "production" ) { console . warn ( format ( message , variables ) ) ; } } export function unreachable ( ) { return bail ( "Entered unreachable code." ) ; }