DrKillshot / unwrap

A functional programming library for typescript developers
https://drkillshot.github.io/unwrap/
1 stars 1 forks source link

Create out of the box Branded types #28

Open DrKillshot opened 1 day ago

DrKillshot commented 1 day ago

With the .combine method we can compose rich and expressive type systems. For example

type NotEmpty = Brand.type<"NotEmpty", string>
const NotEmpty = Brand.define<NotEmpty>(
    str => str.trim().length !== 0,
    "Expected a non-empty string."
)

type LessThan30 = Brand.type<"LessThan30", string>
const LessThan30 = Brand.define<LessThan30>(
    str => str.length < 30,
    str => `Expected a string less than 30 characters. Instead got: ${str}`
)

const NonEmptyStringLessThan30 = Brand.combine<"NonEmptyStringLessThan30", string>(NotEmpty, LessThan30)

NonEmptyStringLessThan30("Hello world!") // Returns "Hello world!" as a NonEmptyStringLessThan30 type
NonEmptyStringLessThan30("    ") // Throws error: "Expected a non-empty string."
NonEmptyStringLessThan30("a-more-than-30-character-string") // Throws error: "Expected a string with less than 30 characters. Instead got: ..."

Types like NotEmpty could be provided out of the box by unwrap to aid domain modelling. More types examples: