Hyperguard
Supercharge your TypeScript type guards with this dead simple object validation library
Install / Use
/learn @shovon/HyperguardREADME
Hyperguard: TypeScript object validation
Hyperguard is a tiny library for validating JavaScript values. Whether they be primitives, such as strings and numbers, or modelling more complex objects, Hyperguard will empower you to express your data validation rules, your way.
Killer Features:
- clear, minimal, and intuitive API, with no hidden surprises
- Powerful TypeScript support to infer static types from schema
- Composable validators, empowering you to define your own rules, your way
- zero dependencies
- install either via npm, or copy and paste the
lib.ts(ordist/lib.jsfor JavaScript) file into your project - no library lock-ins. So you used this library for a day, and now you hate it? As long as the next library defines their own
Validatortype, you should be able to migrate to that other library very easily. Or, you can quickly write your own
Getting Started
Schema creation is done by creating a validator. Hyperguard has simple creators, that will allow you to define your overall schema.
import {
object,
string,
number,
InferType,
either,
Validator,
} from "Hyperguard";
// Create a validator that allows for values to be set to `undefined`
const optional = <T>(validator: Validator<T>) =>
either(validator, exact(undefined));
// You create a whole schema validators by composing other smaller validators
let userSchema = object({
name: string(),
age: number(),
address: optional(
object({
apartment: optional(string()),
streetNumber: string(),
streetName: string(),
})
),
});
type User = InferType<typeof userSchema>;
/*
type User = {
name: string
age: number
address: {
apartment: string | undefined
streetNmber: string
streetName: string
} | undefined
}
*/
A validator has a validate method, which you can invoke for the purposes of validating data.
const data: any = {
name: "Jane",
age: 31,
address: { streetNumber: "123", streetName: "Peaceful Blvd" },
};
const result = userSchema.validate(data);
result.isValid;
// Will be 'true'
// In TypeScript, to cast the above `data` into a `user`, use a type guard
let user: User;
if (result.isValid) {
user = result.value;
}
// Simply defining `const str = result.value` will result in a compile-time
// error; type guards are used for casting purposes
These are the very basics that you can go off of, and start validating your data.
Table of Contents
- Hyperguard: JavaScript object validation
- Getting Started
- Table of Contents
- Usage Guide
- Design Philosophy
- API
- string(): Validator<string>
- number(): Validator<number>
- boolean(): Validator<boolean>
- exact<V extends string | number | boolean | null | undefined>(expected: V): Validator<V>
- either(...alts: Validator<any>[]): Validator<any>
- arrayOf<T>(validator: Validator<T>): Validator<T[]>
- any(): Validator<any>
- objectOf<T>(validator: Validator<T>): Validator<{ [key: string]: V }>
- tuple<T>(validator: Validator<T>): Validator<{ [key: string]: V }>
- except<T, I>(validator: Validator<T>, invalidator: Validator<I>): Exclude<T, I>
- object<V extends object>(schema: { [key in keyof V]: Validator<V[key]> }): Validator<V>
- lazy<V>(schemaFn: () => Validator<V>): Validator<V>
- transform<T>(parse: (value: any) => T): Validator<T>
- chain<T1, T2>(left: Validator<T1>, right: Validator<T2>): Validator<T2>
- fallback<T1, T2>(validator: Validator<T1>, getFallback: () => T2)
- predicate<T>(validator: Validator<T>, pred: (value: T) => boolean)
- replaceError<T>(validator: Validator<T>, createError: (value: any, error: IValidationError) => IValidationError): Validator<T>
- Similar libraries
Usage Guide
The Hyperguard library was designed to be used for the purposes of validating incoming JSON data, whether they be from an HTTP request, an AJAX response, a WebSocket payload, etc.
const data = await fetch(url).then((response) => response.json());
const validation = schema.validate(data);
if (validation.isValid) {
const value = validation.value;
}
Hyperguard becomes especially powerful when larger Validators are comprised from smaller reusable validators, that serve their own purpose. These validators can then be used across multiple larger validators.
Installing
By design, Hyperguard places you under no obligation to use any package manager; you most certainly can copy and paste either lib.ts for TypeScript, dist/lib.js for CommonJS (require), or dist/esm/lib.js for importing via the import statement.
With that said, you are certainly more than welcomed to use a package manager, especially since it will allow you to easily upgrade, without the possibility of errors while copying and pasting.
npm (Node.js, Webpack, Vite, Browserify, or any other that use npm)
If you are using Node.js or a bundler that uses npm, Hyperguard has been published to npm for your convenience. You can install using your preferred package manager. For example:
- npm:
npm install Hyperguard - Yarn:
yarn add Hyperguard - pnpm:
pnpm add Hyperguard
Additional, for the JavaScript CommonJS code, transpilers should not be needed. However if you are having trouble importing Hyperguard into your bundler (Webpack, Vite, Browserify, etc.), then please do open a new issue, and I will investigate.
Importing via CommonJS require
Once installed, you should be able to import the module via CommonJS require, like so:
const parseValidate = require("Hyperguard");
Importing via Node.js' ECMAScript module (import statement)
In a Node.js mjs file, you can simply import using the import syntax.
import * as parseValidate from "Hyperguard";
Deno
With Deno, you can directly import the lib.ts file from GitHub.
import * as parseValidate from "https://raw.githubusercontent.com/shovon/Hyperguard/main/lib.ts";
Browser via import statement (dist/esm/lib.js)
Warning
The
dist/lib.jsfile will not work in browsers!You must use the
dist/esm/lib.jsfile instead!
Option 1: Checking in an original copy of lib.js file into your project
Download or copy & paste the ECMAScript module located in dist/esm/lib.js. Optionally, you can also grab a copy of the sourcemap file at dist/esm/lib.js.map for debugging purposes.
<!-- Minified -->
<script type="module">
import * as parseValidate from "/path/to/Hyperguard/lib
