Unlock Runtime TypeScript Types with DeepKit for Validation and Serialization
This article introduces DeepKit, a TypeScript library that preserves type information at runtime, enabling powerful data validation, serialization, and reflection capabilities for both front‑end and back‑end JavaScript applications.
Background
Earlier we investigated a TypeScript data validation solution and discovered the third‑party library DeepKit, which can retain TypeScript type information at runtime.
What TypeScript Brings
Traditional JavaScript provides no type safety; TypeScript adds static type checking, but its type information is erased during compilation, leaving no runtime overhead.
However, runtime type information can be valuable in many scenarios.
Why Runtime Types Are Needed
Two typical scenarios:
Data Validation
When implementing an API or writing to a database, the incoming data must be validated against the expected type definitions.
Service parameters may be arbitrary; without validation the code can crash.
Database fields have strict types; data must conform before insertion.
Serialization / Deserialization
JSON.parse/stringify lose type fidelity for complex objects such as Date.
const date = new Date();
const dateString = JSON.stringify(date); // "2022-11-02T17:49:03.240Z"
const dateJson = JSON.parse(dateString); // "2022-11-02T17:49:03.240Z"DeepKit makes preserving TypeScript types at runtime possible.
Quick Start
Official docs: https://deepkit.io/
Prerequisites
Install two packages:
@deepkit/type – runtime utilities
@deepkit/type-compiler – type compiler to be added to devDependencies in package.json
npm install --save @deepkit/type
npm install --save-dev @deepkit/type-compilerEnable reflection in tsconfig.json and, if needed, experimentalDecorators.
// tsconfig.json
{
"compilerOptions": {
"module": "CommonJS",
"target": "es6",
"moduleResolution": "node",
"experimentalDecorators": true
},
"reflection": true
}Type Information
Type Objects
Use typeOf to obtain a type object.
import { typeOf } from '@deepkit/type';
type Title<T> = T extends true ? string : number;
typeOf<Title<true>>();
// Type {kind: 5, typeName: 'Title', typeArguments: [{kind: 7}]}Key fields: kind, typeName, typeArguments.
enum ReflectionKind {
never, any, unknown, void, object, string, number, boolean, symbol, bigint,
null, undefined
}Reflection Classes
Useful for complex types such as classes or interfaces.
import { ReflectionClass } from '@deepkit/type';
interface User { id: number; username: string; }
const reflection = ReflectionClass.from<User>();
reflection.getProperty('id'); // ReflectionProperty with type infoValidation
DeepKit provides is and validate functions.
interface People { name: string; age: number; info?: { address?: string; phone: number } }
const peopleA = { name: 'Jack', age: 20 };
const peopleB = { name: 'Peter', age: 18, info: {} };
is<People>(peopleA); // true
is<People>(peopleB); // false
validate<People>(peopleA); // []
validate<People>(peopleB); // [{path: 'info.phone', code: 'type', message: 'Not a number'}]Serialization
Use serialize and deserialize to keep type fidelity.
import { serialize, deserialize } from '@deepkit/type';
class MyModel { id = 0; created = new Date(); constructor(public name: string) {} }
const model = new MyModel('Peter');
const jsonObject = serialize<MyModel>(model);
// { id: 0, created: '2022-11-02T17:49:03.240Z', name: 'Peter' }
const myModel = deserialize<MyModel>({ id: 5, created: 'Sat Oct 13 2018 14:17:35 GMT+0200', name: 'Peter' });
is<Date>(myModel.created); // trueType Decorators
DeepKit offers decorators such as integer, PrimaryKey, maxLength, etc., extending TypeScript types for database‑level constraints.
import { integer } from '@deepkit/type';
type count = integer;
is<count>(1); // true
is<count>(1.1); // falsePerformance Optimizations
Type Caching
Non‑generic type objects are cached, while generic ones are not.
type MyType = string;
typeOf<MyType>() === typeOf<MyType>(); // true
type MyType<T> = T;
typeOf<MyType<string>>() === typeOf<MyType<string>>(); // falseType Compiler
The compiler injects bytecode into the TypeScript AST, which a tiny VM executes at runtime to produce type objects.
More Capabilities
Event system: @deepkit/events
HTTP library: @deepkit/http
RPC services: @deepkit/rpc
ORM: @deepkit/orm
Template engine: @deepkit/templ (incompatible with React)
Full‑stack framework: @deepkit/framework
Conclusion
DeepKit is the first solution that provides a complete set of runtime TypeScript types for JavaScript, enabling shared data models between front‑end and back‑end and a reflection mechanism built on TypeScript.
Limitations include lack of support for external types that are not processed by the DeepKit compiler.
Official site: https://deepkit.io/
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
