npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

typescript-type-validator

v1.1.0

Published

Typescript-first type validator

Downloads

21

Readme

Typescript type validator

NPM Version Build the project

A fully TypeScript-supported type validator that enables type checks at both transpile time and runtime using a flexible schema and input validation.

Features

  • Type-Safe Schema Definition
  • Automatic Type Inference
  • Runtime Validation
  • Nested Objects and Arrays
  • Reusable Validators
  • Flexible Validation Options (ValidateOptions)
  • Custom Type Field Validation

Installation

# yarn
yarn add typescript-type-validator
# npm
npm install typescript-type-validator

Usage

1. Define a Schema

import { field, objectField, arrayField, customField, Type, Validator, TypeFromSchema, FieldOptions } from "typescript-type-validator";

// Define a schema for your data
const userSchema = {
  id: field(Type.Number),                             // required field (default)
  name: field(Type.String),                           // required field (default)
  email: field(Type.String, { optional: true }),      // optional field
  profile: objectField({
    age: field(Type.Number),                          // required field
    verified: field(Type.Bool, { optional: true }),   // optional field
  }),
  tags: arrayField(field(Type.String)),               // required array of strings
  posts: arrayField(objectField({
    title: field(Type.String),
    content: field(Type.String),
    published: field(Type.Bool, { optional: true }),
  }), { optional: true }),                            // optional array of objects
  // Custom field: must be a string that starts with "user_"
  customId: customField((val) => {
    if (typeof val !== "string" || !val.startsWith("user_")) throw new Error("customId must start with 'user_'");
    return val as `user_${string}`;
  }, { optional: true }),
} as const;

2. Get Inferred Type

// TypeFromSchema gives you the TypeScript type for your schema
type User = TypeFromSchema<typeof userSchema>;
// User is:
// {
//   id: number;
//   name: string;
//   email?: string;
//   profile: { age: number; verified?: boolean };
//   tags: string[];
//   posts?: { title: string; content: string; published?: boolean }[];
//   customId?: `user_${string}`; // inferred from the custom field
// }

3. Validate Data at Runtime

const userData = {
  id: 1,
  name: "Alice",
  profile: { age: 30 },
  tags: ["admin", "editor"],
};

const validated = Validator.validate(userSchema, userData);
// validated is now strongly typed as User

// Throws ValidationError if invalid:
try {
  Validator.validate(userSchema, { id: "not-a-number", name: "Bob", profile: { age: 20 }, tags: [] });
} catch (e) {
  console.error(e); // ValidationError with details
}

4. Use with Validation Options

import { ValidateOptions } from "typescript-type-validator";

// Basic validation options
const options: ValidateOptions = {
  strict: true,           // throws on unexpected fields
  rootKey: "request.body" // prefixes all error keys
};

const userData = {
  id: 2,
  name: "Charlie",
  profile: { age: 25 },
  tags: ["user"],
  extra: "not allowed",
};

try {
  Validator.validate(userSchema, userData, options);
} catch (e) {
  console.error(e); // ValidationError: UnexpectedFieldError for key "request.body.extra"
}

// You can also use individual options
Validator.validate(userSchema, userData, { strict: true });
Validator.validate(userSchema, userData, { rootKey: "api.input" });
Validator.validate(userSchema, userData, {}); // default options
Validator.validate(userSchema, userData);     // default options

5. Enhanced Error Context with Root Key

The rootKey option is particularly useful for API validation where you want to provide clear error paths:

const apiSchema = {
  user: objectField({
    profile: objectField({
      name: field(Type.String),
      age: field(Type.Number),
    })
  })
};

try {
  Validator.validate(apiSchema, {
    user: { profile: { name: "John", age: "invalid" } }
  }, { rootKey: "request.body" });
} catch (e) {
  console.error(e.error.key); // "request.body.user.profile.age"
  // Instead of just: "user.profile.age"
}

6. Use as a Class

const userValidator = new Validator(userSchema);

// Same API as static method
const validUser = userValidator.validate({
  id: 3,
  name: "Dana",
  profile: { age: 40, verified: true },
  tags: [],
});

// With options
const validUserStrict = userValidator.validate(userData, { strict: true });

7. Custom Type Field Validation

You can define custom fields using your own resolver functions. The resolver receives the input value and must return the validated value. The return type will be inferred automatically.

import { customField, Validator, TypeFromSchema } from "typescript-type-validator";

const schema = {
  evenNumber: customField((val, key) => {
    if (typeof val !== "number" || val % 2 !== 0) throw new Error(`Not an even number under key: ${key}`);
    return val; // must return the original value
  }),
  optionalEvenNumber: customField((val, key) => {
    if (typeof val !== "number" || val % 2 !== 0) throw new Error(`Not an even number under key: ${key}`);
    return val;
  }, { optional: true }),
};

type CustomType = TypeFromSchema<typeof schema>;
// CustomType is: { evenNumber: number; optionalEvenNumber?: number }

Validator.validate(schema, { evenNumber: 4 }); // OK
Validator.validate(schema, { evenNumber: 3 }); // Throws error

Field Options

All field functions (field, objectField, arrayField, customField) support the FieldOptions parameter:

type FieldOptions = { optional?: boolean };

// Examples:
field(Type.String)                     // required (default)
field(Type.String, {})                 // required (explicit)
field(Type.String, { optional: false }) // required (explicit)
field(Type.String, { optional: true })  // optional

objectField(schema)                    // required (default)
objectField(schema, { optional: true }) // optional

arrayField(innerField)                 // required (default)
arrayField(innerField, { optional: true }) // optional

customField(resolver)                  // required (default)
customField(resolver, { optional: true }) // optional

Validation Options

The ValidateOptions type provides flexible validation configuration:

type ValidateOptions = {
  strict?: boolean;   // Default: false - throws on unexpected fields when true
  rootKey?: string;   // Default: undefined - prefixes all error keys
};

// Usage examples:
Validator.validate(schema, data)                                    // defaults
Validator.validate(schema, data, {})                               // explicit defaults
Validator.validate(schema, data, { strict: true })                 // strict mode only
Validator.validate(schema, data, { rootKey: "api.request" })       // error context only
Validator.validate(schema, data, { strict: true, rootKey: "body" }) // both options

Exports available:

  • field, objectField, arrayField, customField — for schema definition
  • Type — enum for field types
  • FieldOptions — type for field configuration options
  • ValidateOptions — type for validation configuration options
  • TypeFromSchema — type inference from schema
  • Validator — class and static method for validation