import { Option as O, Predicate } from 'effect' export type Primitive = string | number | boolean | undefined | null export type Discriminated< Type, Field extends string & keyof Type, Value extends Primitive & Type[Field], > = Type & { [field in Field]: Value } export const discriminate = < Type, Field extends string & keyof Type, Value extends Primitive & Type[Field], >( discriminatorField: Field, discriminator: Value ) => (a: Type): a is Discriminated => { return a[discriminatorField] === discriminator } export const discriminateA = < Type, Field extends string & keyof Type, Value extends Primitive & Type[Field], >( discriminatorField: Field, discriminator: Value[] ) => (a: Type): a is Discriminated => { return discriminator.includes(a[discriminatorField] as any) } export const oLiftRefinement = ( refinement: Predicate.Refinement ): ((a: A) => O.Option) => O.liftPredicate(refinement)