Introduction
It is very common to bring your own, I built this library specifically for that actually ; because we all have our concepts which vary on the industry we work in and how our business models are defined.
Without branded types
import * as x from 'unhoax'
declare const isEmail: (value: string) => boolean
const refineAsEmail = x.refine('Email', isEmail)
const emailSchema = refineAsEmail(x.string)
// x.Schema<string>
// or, using pipe
import pipe from 'just-pipe'
const emailSchema = pipe(x.string, x.refine('Email', isEmail))
With branded types
Let’s consider a simple branded string to represent an email:
type Email = string & { _tag: 'Email' }
// this time, we have a type guard.
declare const isEmail: (value: string) => value is Email
Now let’s build the schema:
import * as x from 'unhoax'
const refineAsEmail = x.refineAs('Email', isEmail)
const emailSchema = refineAsEmail(x.string)
// x.Schema<Email>
// or, using pipe
import pipe from 'just-pipe'
const emailSchema = pipe(x.string, x.refineAs('Email', isEmail))
// x.Schema<Email>
Summing up – x.refine
vs x.refineAs
x.refine
does not change the schema type:x.refine(schema<T>, isX) => schema<T>
x.refineAs
does change the schema type:x.refineAs(schema<T>, isU) => schema<U>