typesafe-joi is a fork of @hapi/joi. More precisely, this is a fork of @types/hapi__joi because it has just redefined the essential APIs of joi. Almost all the APIs are the same as the original APIs, but limitations exists. That is why I create a new package.
typesafe-joi currently matches the API of @hapi/joi 15.x. And it requires TypeScript >=3.0.0 to work.
NOTE: typesafe-joi is still WIP. Sorry but I do not have enough time to write a unit test for it. Please feel free to open an issue when you find bugs or suggestions. I am glad to help!
What’s the difference?
The JavaScript APIs of typesafe-joi and joi are identical. However, its type definition lacks of the type information of the “value” behind the schema. That means, JavaScript knows what the validated object look like at runtime, but TypeScript does not know it at all at compile time. typesafe-joi records more information into schemas so that TypeScript is able to know what object you are validating at compile time.
Unfortunately not all joi APIs are able to be properly described in TypeScript. See Reference for more information.
Usage
Import and use joi from typesafe-joi:
import*asJoifrom'typesafe-joi'
The TypeScript magic is shown when you call .validate or .attempt:
You can also use Literal to pull the data type out of the schema:
constschema=Joi.array()
.items({
id:Joi.number().integer().required(),
email:Joi.string().email()
})
.required()
typeT=Joi.Literal<typeofschema>
NOTE: I suggest to turn on strict option in the compiler options of TypeScript.
Typecasting
Not every API of typesafe-joi matches the original joi in types. typesafe-joi provides typecast helpers in case you have to define the resulting type manually.
// 'foo'
Joi.string().required()asJoi.Cast.String<'foo'>
If the typecast includes undefined type, the key will be optional.