Installation
npm i toa-sharp
Usage
Define a sharp
const sharp = Sharp.make((s) =>
s.Struct({
id: s.ObjectID,
name: s.String,
age: s.Optional(s.Number)
address: s.Array(s.String)
})
)
// stands for type => {
// id: ObjectID // string with objectId constraint
// name: string
// age: number | undefined
// address: string[]
// }
Primitive
s.Never
s.String
s.Number
s.Boolean
s.Unknown
Combinators
s.Literal
constructor
The -
s.Literal(null)
=>null
-
s.Literal(undefined)
=>undefined
-
s.Literal('ON')
=>'ON'
-
s.Literal('ON', 'OFF')
=>'ON' | 'OFF'
s.Nullable
constructor
The s.Nullable(s.String)
=> string | null
s.Optional
constructor
The s.Optional(s.String)
=> string | undefined
Notice that it DOES NOT mean the key is optional (key?: string
)
s.Struct
constructor
The s.Struct({ id: s.String, time: s.Number })
=> { id: string, time: number }
s.Partial
constructor
The s.Partial({ id: s.String, time: s.Number })
=> { id?: string, time?: number }
s.Map
constructor
The s.Map(s.Boolean)
=> Record<string, boolean>
s.Array
constructor
The s.Array(s.Number)
=> number[]
s.Tuple
constructor
The s.Tuple(s.String, s.Number)
=> [string, number]
s.Intersection
constructor
The s.Intersection(s.Struct({ name: s.String }), s.Partial({ age: s.Number }))
=> { name: string } & { age?: number }
s.Union
constructor
The s.Union(s.String, s.Number)
=> string | number
s.Enum
constructor
The To compatible with Typescript enum when there is no other choice, it's not well supported due to a poor design, highly recommend using s.Literal
instead.
// MUST NOT be a `const enum`, otherwise it will be optimized out.
enum Toggle {
On = "ON",
Off = "OFF",
}
s.Enum("Toggle", Toggle); // => Toggle
// You have to specify enum type when it's a numeric enum,
// however numeric enums are unsafe in typescript, shouldn't be used anyway.
// @see https://github.com/gcanti/io-ts/issues/216#issuecomment-621615906
enum ToggleNumber {
On,
Off,
}
s.Enum<ToggleNumber>("ToggleNumber", ToggleNumber); // => ToggleNumber
Brand
- the
s.ObjectID
is string with ObjectID constraint, it can pass to string
Assertion
Say we are using koa(with body-parser), to assert body sharp you can
import { Sharp, assert } from "toa-sharp";
import { Errors } from "./errors";
const Body = Sharp.make((s) => S.Struct({ id: s.ObjectID, text: s.String }));
async function handler(ctx: Context) {
assert(ctx.request.body, Body, new Errors.InvalidParams());
const { id, text } = ctx.request.body; // with type { id: ObjectID, text: string }
}
The third argument can receive a Error | ErrorContructor
, the Error instance will be threw directly while the ErrorContructor will receive error message as first argument.
By default it's TypeError
constructor.
Roadmap
- Add branded type such as Int(number), Positive(number), Email(string), Url(string), etc.