Typesmith: Easy Runtime Validation
Inspired by typescript-is.
Transforms typescript interfaces, classes and other types into runtime validation functions. It leverages these fine libraries:
- ts-json-schema-generator - Generate JSON Schema from Typescript AST
- ajv - Validates an object against JSON Schema
- ajv-keywords - Additional validation capabilities via custom JSON Schema keywords
💿 Quick Start Guide
-
Install typesmith
npm i --save typesmith -
Install ttypescript
npm i --save-dev ttypescript -
Edit your tsconfig.json to use the plugin
-
Replace
tsc ...
commands withttsc ...
commands.
📐 Example
; ; ;;; // Validation Successful ResultassertPersonjillSmith.isSuccess === true;assertPersonjillSmith.unwrap === jillSmith;assertPersonjillSmith.getErrors === null;assertPersonjillSmith.getOrElsejaneDoe === jillSmith;assertPersonjillSmith.getOrElseLjaneDoe === jillSmith; // Validation Failure ResultassertPersoninvalidPerson.isSuccess === false;assertPersoninvalidPerson.unwrap; // Throws ErrorassertPersoninvalidPerson.getErrors.length > 0;assertPersoninvalidPerson.getOrElsejaneDoe === janeDoe;assertPersoninvalidPerson.getOrElseLjaneDoe === janeDoe;
🎛️ Options
- allErrors: (default: true) returns all errors instead of returning only the first one
- removeAdditional: (default: false) remove additional properties
- useDefaults: (default: false) replace missing or undefined properties and items with the values from corresponding default keywords
- coerceTypes: (default: false) change data type of data to match type keyword
- lazyCompile: (default: true) wait to compile validation function until first use
Options are specifiable at the global and type level, EG:
; // Globally:settings.updateGlobalValidationOptions; // Type-LevelassertTypeFn;
💣 Caveats
Compiler crashes in rare but specific circumstances:
- Mixin classes:// Crashes
Anonymous recursive generic types:// Okay;assertTypeFn;// (Works as of v0.9.8)assertTypeFn;
AJV's type coercion ineffective for primitives
With AJV's coerceTypes
enabled, coerced primitives will validate but will return the original value. EG:
// Coercion of boxed value worksassertTypeFn.unwrap.value === 12;// Coercion of primitive doesn'tassertTypeFn"12".unwrap === "12"
@Validate() w/ Generic Type Parameters
Defaults must be provided to classes with generic type paramters. EG:
// Okay // Crashes
Dates
TODO
note: try using { DateInstance, DateTimeFlex, DateTimeString } from "typesmith"
✔ Todo
Features
- feat: allow strings to be coerced to other primitives without using AJV's built-in coercion since it is too lenient. EG,
false
shouldn't be coerced to0
- feat: use ajv-pack for precompiled validation functions. ajv-pack has restrictions so this would need to be optional.