Dead simple applicative validation tools with a few simplifications making for more idiomatic TypeScript/JavaScript usage.
test('lift', () => {
type Sex = 'm' | 'f'
const Person = class {
constructor(public age: number, public sex: Sex) {}
static of(age: number, sex: Sex) {
return new Person(age, sex)
}
}
expect(assert(lift(Person.of, valid(25), valid('m' as Sex))))
.toBeInstanceOf(Person)
expect(() => assert(lift(Person.of, invalid("Age was NaN"), valid('m' as Sex))))
.toThrowError("Age was NaN")
})
Create Valid<T>
and Invalid
types and combine them with
function application combinators.
The union type that forms the basis for our combinators
Cast a type to a valid kind
Create an invalid kind by passing validation messages
Map the valid kind of a type to another type or else get the err back.
Reduce a list of valid kinds of A
to valid kinds of B
or else
exclusively get back the errors in that original list
The primary tool, accepts a function and the Assert
kind of its
argument types, and returns the Assert
kind of its return type