TypeGuards
Runtime type checking library for TypeScript & JavaScript.
✨ Features
- Provides runtime type validation.
- Can derive static type from any type guard, thus types are never out of sync.
- Supports nested type guards.
- Supports almost all JS data types, including Promise, Proxy, DataView and typed arrays.
- Package has 0 dependency.
📦 Installation
# npm
npm install @typeguards/core
# yarn
yarn add @typeguards/core
🔨 Usage
Basics
import T from '@typeguards/core'
T.Number.validates(1) // true
T.Number.validates('1') // false
T.Optional(T.String).validates('1') // true
T.Optional(T.String).validates(undefined) // true
T.Optional(T.String).validates(1) // false
// Custom type guard
const Range = T.Number.config({
// Custom validation function
validate: value => typeof value === 'number' && value > 0 && value < 3,
})
Range.validate(0) // false
Range.validate(1) // true
Range.validate(2) // true
Range.validate(3) // false
Schema
import type { Static } from '@typeguards/core'
import T, { createSchema } from '@typeguards/core'
const Age = T.Number.config({ validate: v => typeof v === 'number' && v >= 0 })
// Custom schema
const JobSchema = T.Schema({
title: T.String,
salary: T.Nullable(T.Number),
})
// Use closure to use type guard directly & prevent naming conflicts with JS built-in objects
const PersonSchema = createSchema(({ Boolean, String, Number, Array, Optional, Union }) => ({
name: String,
age: Age,
alive: Boolean,
address: Optional(String),
// Support complex nested type guard
favorites: Array(Union(String, Number)),
// Support nested schema
job: JobSchema,
}))
// Support static type derivation, thus type is never out of sync
const person: Static<typeof PersonSchema> = {
name: 'John Doe',
age: 23,
alive: true,
address: undefined,
favorites: ['cat', 'dog', 7],
job: {
title: 'Dreamer',
salary: null,
},
}
PersonSchema.validate(person) // true
PersonSchema.validate({ ...person, address: undefined }) // true, because address is optional
PersonSchema.validate({ ...person, name: undefined }) // false
PersonSchema.validate({ ...person, age: '23' }) // false
const CatSchema = T.Partial(T.Pick(PersonSchema, ['name', 'age', 'alive']))
// Equivalent to Partial<Pick<PersonType, 'name' | 'age' | 'alive'>>
type Cat = Static<typeof CatSchema>
CatSchema.validate(person) // false
CatSchema.validate({ name: 'Baby', age: undefined }) // true
// Retrieve Schema definition
const catDefinition = CatSchema.definition() // { name: String, age: Age, alive: Boolean }
// Retrieve Indexed access type definition, which is a type guard in this case
const CatName = CatSchema.definition('name') // T.String
CatName.validate('str') // true
catDefinition.name.validate('str') // true
Transformer (Experimental Feature)
import T from '@typeguards/core'
// Customize transformation function
const Name = T.String.config({ transform: val => `${val} Jr.` })
const Alive = T.Boolean.config({ transform: val => val ?? true })
const Person = T.Partial(T.Schema({ name: Name, alive: Alive }))
const john = { name: 'John' }
Person.validate(john) // true
const johnJr = Person.transform(john) // { name: 'John Jr.', alive: true }
🛡️ List of type guards
name | description |
---|---|
Boolean | |
StringBoolean | "true" | "TRUE" | "false" | "FALSE" | "1" | "0" |
Number | |
NaN | NaN |
PositiveNumber | A number value that's greater than 0 |
NegativeNumber | A number value that's less than 0 |
BigInt | |
PositiveBigInt | A BigInt value that's greater than 0 |
NegativeBigInt | A BigInt value that's less than 0 |
StringNumber | A string whose value is a number, such as "0", "-1", "3.333" |
String | |
NonEmptyString | A string that's not empty even after trimming |
Symbol | |
Undefined | undefined |
Null | null |
Object | An object (Any object will qualify as long as typeof obj === 'object' ) |
RegExp | |
Map | |
WeakMap | |
Set | |
WeakSet | |
Promise | |
Proxy | |
Date | |
StringDate | A correctly formatted date string, such as "1996-07-23", "1996/07/23", "1996 Jul", "1996" |
Array | |
StringArray | A string whose value is an array separated by delimiter "," (delimiter is customizable) |
ArrayBuffer | |
SharedArrayBuffer | |
DataView | |
Int8Array | |
Uint8Array | |
Uint8ClampedArray | |
Int16Array | |
Uint16Array | |
Int32Array | |
Uint32Array | |
Float32Array | |
Float64Array | |
BigInt64Array | |
BigUint64Array | |
Function | A function |
Schema | A plain object |
Optional | T | undefined |
Nullable | T | null |
Never | Equivalent of TypeScript never type |
Unknown | Equivalent of TypeScript unknown type |
Any | Equivalent of TypeScript any type |
Record | Equivalent of TypeScript Record type |
Partial | Equivalent of TypeScript Partial type |
Required | Equivalent of TypeScript Required type |
Pick | Equivalent of TypeScript Pick type |
Omit | Equivalent of TypeScript Omit type |
NonNullable | Equivalent of TypeScript NonNullable type |
Union | Equivalent of TypeScript union type |
Const | Equivalent of TypeScript const assertion |
GeneratorFunction | Requires ES6/ES2015 or later |
Generator | Requires ES6/ES2015 or later |
AsyncFunction | Requires ES8/ES2017 or later |