Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

πŸ›‘οΈ type-assurance

npm bundle size

Super lightweight TypeScript library to perform type checks at runtime.

  • Does only one thing: runtime type checking
  • Provides type guards and type assertions
  • Intuitive schema definition based on language literals
  • 100% test coverage


Let's start with a simple example:

import { assert } from "type-assurance";

const userSchema = {
  name: String;
  email: String;

const user = await api.getUser(23);

// Throw if types don't match
assert(user, userSchema);

// The compiler now knows the type ...

We can also infer a static TypeScript type from the runtime schema:

import { TypeFromSchema } from "type-assurance";

type User = TypeFromSchema<typeof userSchema>;

This yields the same type as if we had written it by hand:

type User = {
  name: string;
  email: string;

Sometimes all you need is a quick inline type-check. Use is instead of assert which acts as a type-guard:

import { is } from "type-assurance";

if (
  is(data, {
    body: {
      posts: [
          id: Number,
          title: String,
) {
  // We can now be certain that the given data
  // has the expected shape and the compiler
  // now knows about the types...


You can install the package from npm:

npm install type-assurance

πŸ¦• The package is also published under for use with Deno.


The package exports the following main functions:

  • is(value, schema) – returns true if the value matches the schema. The return type is a type predicate that narrows the type down to the one described by the schema.
  • assert(value, schema) – throws a TypeError if the value does not match the schema. It is an assertion function that narrows the type down to the one described by the schema.
  • typeGuard(schema) – returns a function that can be used as type guard for the given schema.

The schema that is passed to both these functions looks like an example or blueprint of the expected type. It can be a deeply nested object or just a single value.


You can use String, Number or Boolean as schema for primitive types:

is(42, Number); // βœ… true
is("42", Number); // ❌ false
is("foo", String); // βœ… true

This isn't particularly helpful on its own, but it makes sense when used to describe more complex shapes.


To specify objects, use an object where each value is again a schema:

import { typeGuard } from "type-assurance";

const isUser = typeGuard({
  post: {
    id: Number,
    author: {
      name: String,

const data = JSON.parse(`{
  "post": {
    "id": 23,
    "author": {
      "name": "Felix"

if (isUser(data)) {
  // is a string βœ…


You can use constructor functions as schema to check if an object is an instance of that type:

assert(data, {
  now: Date,
  pattern: RegExp,

This also works for classes:

class Person {
  constructor(public name: string) {

const data: unknown = {
  user: new Person("Felix");

if (is(data, { user: Person })) {
  // data.user is a Person

NOTE: In the very unlikely case that you want to test for String, Number or Boolean objects, you have to use a function instead:

is("foo", String); // βœ… true
is(new String("foo"), String); // ❌ false
is(new String("foo"), (s) => s instanceof String); // βœ… true


To specify an array of a certain type, wrap that type in an array:

assert(data, [Number]);
// data is of type number[]


For tuples, provide an array with more than one item:

assert(value, [Number, String, Boolean]);
// value[0] is a number
// value[1] is a string
// value[2] is a boolean

Custom type guards

You can also use type guard functions as (nested) schemas:

 * Type guard to test if the given value is SomeFancyType.
function isSomeFancyType(v: unknown): v is SomeFancyType {
  // custom check goes here ...

assert(data, {
  id: Number,
  body: isSomeFancyType,


Finally, specific strings, numbers or boolean values are treated as literal types:

const personSchema = {
  type: "person",
  name: String
} as const;

const dogSchema = {
  type: "dog",
  name: String,
  breed: String,

if (is(data, dog)) {
  console.log( "is a cute", data.breed);

Union Types

The package exports a union function to check if a value is of either of the given types:

import { union } from "type-assurance";

const taskSchema = {
  title: String,
  status: union("pending", "active", "done"),

Optional properties

You can use the optional helper for properties that aren't required:

import { optional } from "type-assurance";

const personSchema = {
  name: String
  address: optional(String)

Note The optional(schema) helper is short for union(schema, undefined);

Infer the type from a schema

You can convert a runtime schema into a static type:

import { TypeFromSchema } from "type-assurance";

const PersonSchema = {
  name: String;
  age: Number;

type Person = TypeFromSchema<typeof PersonSchema>;




Lightweight type guards and assertions






No packages published