@deepkit/type

Rich runtime type system for TypeScript with reflection, serialization, validation, and many more features. Works in any JavaScript runtime without code generation step. Plugins available for TypeScript official compiler tsc, Vite, Bun, and Webpack.

Features

Runtime Types
Makes TypeScript types available in any JavaScript runtime.
Validation
With powerful validation of your TypeScript types, without code-generation step.
Serialisation
Fast and flexible serialisation from and to JSON, database, BSON, and more.
Reflection
Introspect all types via standardised in runtime and unlock TypeScript at runtime.
Automatic Type-Guards
Type-Guards and Type-Assertions in runtime, automatically from your types.
Highly Customizable
Add your own custom type annotation, serializers, naming strategies, and more.

Runtime TypeScript Types

Deepkit Type provides a rich runtime type system for TypeScript. It allows you to use your TypeScript types in any JavaScript runtime, like Node.js, Deno, or the browser.

import { MinLength, stringifyResolvedType, 
    typeOf } from '@deepkit/type';

type Username = string & MinLength<3>;

interface User {
    username: Username;
    password: string;
    created: Date;
}

const type = typeOf<User>();
console.log('Type introspection', type);
console.log('Type stringify', stringifyResolvedType(type));

Type Cast

Real type casting in runtime for TypeScript. This is not a type assertion, but a real type cast. It converts the value to the correct type.

Whenever you load data from a database, HTTP request, JSON, or any other source, you can use cast to convert the data to the correct type.

import { cast } from '@deepkit/type';

interface User {
    username: string;
    logins: number;
    created: Date;
}

// converts all values to the correct type
const user = cast<User>({
    username: 'Peter',
    logins: '3',
    created: '2020-01-01'
});

Reflection API

Easy to use reflection API to introspect your types. This is especially useful for building generic libraries that work with any TypeScript type.

With the reflection API you can get all properties of classes, interfaces, or functions, properties, all methods, their parameters, and more.

import { ReflectionClass } from '@deepkit/type';

class User {
    logins: number = 1;
    created: Date = new Date;

    constructor(public username: string) {
    }
}

const reflection = ReflectionClass.from(User);

reflection.getMethodParameters('constructor');
for (const p of reflection.getProperties()) {
    p.name;
    p.type;
    p.isOptional();
    p.getVisibility();
}

Serialization

Serialize data to JSON, BSON, or any other format. The serialization is very fast and flexible. You can use it to serialize data for HTTP responses, databases, queues, files, or any other use case.

Highly configurable and extensible. You can add your own custom types, custom serializers, custom naming strategy, and more.

Use serialize to convert your data to a plain JavaScript object, and cast to convert it back.

import { serialize, cast } from '@deepkit/type';

interface User {
    username: string;
    logins: number;
    created: Date;
}

// jsonObject is a plain JavaScript object
// and ready for transport via JSON.stringify
const jsonObject = serialize<User>({
    username: 'Peter',
    logins: 3,
    created: new Date,
});

// convert back from transport to real JavaScript types
const user = cast<User>(jsonObject);

Type Object Serialization

Deepkit Type provides a special serialization format for TypeScript types. This is useful if you want to send your TypeScript types to another JavaScript runtime, like the browser, or a Node.js worker.

This makes it possible to store the inherently circular TypeScript type object in a JSON.

import { serializeType, deserializeType, 
    cast } from '@deepkit/type';

interface User {
    username: string;
    logins: number;
    created: Date;
}

// typeObject is ready for transport via JSON.stringify
const typeObject = serializeType(typeOf<User>());

// convert back from transport to Deepkit's circular type object
const type = deserializeType(typeObject);

// and use it in cast/deserialize/validate, etc
const o = cast(data, undefined, undefined, undefined, type);

Remapping

As a data mapper, Deepkit Type can convert your data from one shape to another.

Support for custom naming strategies. You can use this to convert your property names to camelCase, snake_case, or any other naming strategy.

import { cast, MapName,
    underscoreNamingStrategy} from '@deepkit/type';

interface User {
    username: string;
    firstName: string;
    group: string & MapName<'group_id'>;
}

const jsonObject = {
    username: 'pete',
    first_name: 'Peter',
    group_id: 'admin'
};

// user has the shape of User
const user = cast<User>(data, undefined, 
    undefined, underscoreNamingStrategy);

Type Guards

TypeScript type guards in runtime. Whenever you accept untrusted data or any, you can use is to check if the data is of a specific type.

Type Assertion with assert to check the data and throw an error if it is not of the expected type.

import { is, assert} from '@deepkit/type';

interface User {
    username: string;
    firstName: string;
    group: string & MapName<'group_id'>;
}

const user = await fetch('/user/1');
if (is<User>(user)) {
    // user object has been validated and its safe
    user.username;
}

// throws an error if user is not of type User
assert<User>(user);

Questions & Answers

1. What is the primary purpose of the Deepkit Type library?

The primary use-case of Deepkit Runtime Types is to make TypeScript types available in runtime and enable with it a big range of use-cases. Many of them like validation and serialisation is already covered in Deepkit Runtime Types.

2. How does Deepkit Type integrate with existing TypeScript projects

Deepkit Type integrates with existing TypeScript projects by providing a plugin for either TypeScript compiler (which is compatible with Angular, React, ts-node, etc), or as Vite, Webpack, or Bun plugin. Once installed, Deepkit Type can be used right away in your TypeScript code without any code generation steps.

3. What kind of validation can I perform using Deepkit Type?

Deepkit Type provides a powerful validation engine that can validate any data structure against a given type. It supports almost all TypeScript types, including generics, unions, intersections, mapped types, conditionals, index access, and more.

4. What kind of serialization can I perform using Deepkit Type?

Deepkit Type provides a powerful serialization engine that can serialize any data structure into a target structure. It comes with JSON and BSON serializer and can be extended with custom serializers. It supports almost all TypeScript types, including generics, unions, intersections, mapped types, conditionals, index access, and more.

5. How does it compare to Zod, io-ts, and other validation libraries?

Deepkit Type is a full-featured TypeScript runtime type system that can be used for validation, serialization, and more. It is not only a validation library, but a full-featured runtime type system that can be used for much more.

While you define your schemas in Zod & co using a custom DSL with an expensive type inference step, Deepkit Type uses just TypeScript types and enriches the type system with Type Annotations to allow to define validation constraints. This way it's much more powerful as it allows the expressiveness of TypeScript types and does not force you to learn a new DSL.

No answer for your question? Ask a question or see all questions.

See all questionsAsk a question

Examples

Made in Germany