/** * This module provides classes for mimicking type level pattern matching * commonly found in functional programming languages in JavaScript. * * JavaScript already provides the "case" statement which allows for c * onditional execution of a block based on a value. The API allows for the * same except the *type* of the value is used instead. */ import { Type } from '../../data/type'; export { Type }; export interface Case { /** * test a value to determine whether it matches the Case's pattern. */ test(value: Type): boolean; /** * apply the Case's action to a value. * * NOTE: This should only be called if test() returns true. */ apply(value: Type): T; } /** * MatchedValue is the actual type of a value that has been pattern matched by a * Case class. * * When using String,Boolean or Number to pattern match, the value has the type * of string,boolean or number respectively. * * When using a constructor function to pattern match, the value has the type * constructed by the constructor function. * * When using an object to pattern match, the value's type is an object * with corresponding keys each of which following the previous rules * recursively. */ export type MatchedValue = A extends StringConstructor ? string : A extends BooleanConstructor ? boolean : A extends NumberConstructor ? number : A extends new (...args: Type[]) => infer T ? T : { [K in keyof A]: MatchedValue; }; /** * TypeCase is provided for situations where it is better to extend * the Case class instead of creating new instances. */ export declare class TypeCase implements Case { pattern: P; handler: (value: MatchedValue

) => T; constructor(pattern: P, handler: (value: MatchedValue

) => T); /** * test a value to determine whether this Case class can handle it. */ test(value: Type): boolean; /** * apply the handler with a value. * * NOTE: This should not be called if test() fails for the value. */ apply(value: Type): T; } /** * Default is used to match any value. * * Use it as a catch-all when other TypeCase classes fail to match. */ export declare class Default implements Case { handler: (value: Type) => T; constructor(handler: (value: Type) => T); test(_: Type): boolean; apply(value: Type): T; } /** * CaseFunction is a composite class for TypeCases. * * When using this TypeCase it may be necessary to cast the cases value * to a single type the compiler understands. */ export declare class CaseFunction implements Case { cases: Case[]; constructor(cases?: Case[]); test(value: Type): boolean; apply(value: Type): T; }