deepkit/type für TypeScript: Komplettguide mit Beispielen
In der Welt von TypeScript gibt es ein grundlegendes Problem: Typen existieren nur zur Kompilierzeit. Nach der Transpilierung nach JavaScript gehen alle Typinformationen verloren. Dies macht Runtime-Validierung, dynamische Serialisierung oder den Aufbau komplexer Systeme, die auf Typ-Metadaten angewiesen sind, unmöglich. Die Bibliothek deepkit/type löst dieses Problem radikal – sie überführt das TypeScript-Typsystem in die Runtime und ermöglicht es, mit Typen wie mit Daten zu arbeiten.
Der Hauptvorteil von deepkit/type liegt darin, dass keine doppelten Schemata (wie bei Zod oder Yup) geschrieben werden müssen. Sie definieren Typen einmal – in reinem TypeScript – und die Bibliothek extrahiert sie automatisch in die Runtime. Dies ermöglicht Datenvalidierung, Serialisierung/Deserialisierung, Reflexion (Abrufen von Informationen über Eigenschaften, Generics, Decoratoren) und sogar die Codegenerierung auf Basis von Typen. deepkit/type ist nicht nur ein Validator, sondern ein vollwertiges Framework für Metaprogrammierung.
Die Bibliothek eignet sich ideal für Projekte, bei denen eine strenge Typisierung auf allen Ebenen wichtig ist: API-Server (Validierung eingehender Anfragen), Datenbanken (Typ-Mapping in SQL), Konfigurationsdateien, RPC-Systeme und Tools zur Codegenerierung. Dank der Integration mit deepkit/framework wird sie auch zur Erstellung leistungsstarker Serveranwendungen mit automatischer Validierung und Serialisierung verwendet.
Installation
deepkit/type ist ein npm-Paket für TypeScript. Die Installation erfolgt mit dem Standardbefehl:
npm install @deepkit/type reflect-metadata
Außerdem müssen Sie Ihre tsconfig.json für die Unterstützung von Decoratoren und die Ausgabe von Metadaten konfigurieren:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"strict": true,
"target": "ES2020",
"module": "commonjs",
"outDir": "./dist"
}
}
Wenn Sie ts-node zum Ausführen verwenden, stellen Sie sicher, dass es zuerst reflect-metadata lädt. Fügen Sie am Anfang Ihrer Einstiegsdatei hinzu:
import 'reflect-metadata';
Schnellstart
Ein minimales Beispiel zeigt, wie Sie einen Typ deklarieren und seine Runtime-Darstellung abrufen:
import 'reflect-metadata';
import { typeOf, ReflectionClass } from '@deepkit/type';
// Interface deklarieren
interface User {
id: number;
name: string;
email?: string;
}
// Runtime-Typ abrufen
const userType = typeOf();
console.log(userType); // ReflectionClass
// Eigenschaften prüfen
const reflection = ReflectionClass.from(userType);
console.log(reflection.getProperty('name').type); // ReflectionProperty
console.log(reflection.getProperty('id').type.kind); // 'number'
Dieser Code gibt die Typinformationen für User in der Konsole aus. Beachten Sie: Wir haben keine Schemata geschrieben – nur ein reines TypeScript-Interface.
Wichtige Methoden und Funktionen
Nachfolgend finden Sie die wichtigsten Funktionen von deepkit/type. Für jede Methode sind die Signatur, eine kurze Beschreibung und ein funktionierendes Beispiel angegeben.
1. typeOf
Signatur: typeOf<T>(): ReflectionClass
Funktion: Extrahiert die Runtime-Darstellung des Typs T. Gibt ein ReflectionClass-Objekt zurück, das vollständige Informationen über die Typstruktur enthält: Eigenschaften, deren Typen, Modifikatoren (optional, readonly), Generics und Decoratoren.
import { typeOf } from '@deepkit/type';
interface Product {
id: number;
title: string;
price: number;
}
const productType = typeOf();
console.log(productType.getProperty('title').type.kind); // 'string'
console.log(productType.getProperty('price').type.kind); // 'number'
2. is
Signatur: is<T>(value: unknown): value is T
Funktion: Führt eine Runtime-Validierung durch und prüft, ob ein Wert dem Typ T entspricht. Gibt einen Type Guard zurück, sodass TypeScript den Wert nach der Prüfung automatisch als T typisiert.
import { is } from '@deepkit/type';
interface User {
id: number;
name: string;
}
const data: unknown = { id: 1, name: 'Max' };
if (is(data)) {
console.log(data.name); // TypeScript weiß jetzt, dass data ein User ist
}
3. cast
Signatur: cast<T>(value: unknown): T
Funktion: Wandelt einen unbekannten Wert in den Typ T um. Dabei werden Typkonvertierungen (z. B. String zu Number) und Standardwerte angewendet. Wirft einen Fehler, wenn die Konvertierung fehlschlägt.
import { cast } from '@deepkit/type';
interface Config {
port: number;
host: string;
}
const raw = { port: '3000', host: 'localhost' };
const config = cast(raw);
console.log(config.port); // 3000 (als Zahl)
4. serialize
Signatur: serialize<T>(value: T): unknown
Funktion: Serialisiert einen typisierten Wert in ein einfaches JavaScript-Objekt. Entfernt Methoden und nicht-serialisierbare Eigenschaften. Ideal für die JSON-Ausgabe.
import { serialize } from '@deepkit/type';
class User {
constructor(public id: number, public name: string) {}
}
const user = new User(1, 'Anna');
const serialized = serialize(user);
console.log(serialized); // { id: 1, name: 'Anna' }
5. deserialize
Signatur: deserialize<T>(value: unknown): T
Funktion: Deserialisiert ein einfaches JavaScript-Objekt zurück in einen typisierten Wert. Stellt sicher, dass die Daten dem Typ T entsprechen.
import { deserialize } from '@deepkit/type';
interface User {
id: number;
name: string;
}
const data = { id: 1, name: 'Ben' };
const user = deserialize(data);
console.log(user.name); // 'Ben'
6. ReflectionClass und ReflectionProperty
Signatur: ReflectionClass.from(type: ReflectionClass): ReflectionClass
Funktion: Ermöglicht die detaillierte Inspektion von Typen zur Laufzeit. Sie können Eigenschaften, deren Typen, Decoratoren und sogar Generics abfragen.
import { typeOf, ReflectionClass } from '@deepkit/type';
interface User {
id: number;
name: string;
email?: string;
}
const userType = typeOf();
const reflection = ReflectionClass.from(userType);
// Alle Eigenschaften durchgehen
for (const property of reflection.getProperties()) {
console.log(`Eigenschaft: ${property.name}, Typ: ${property.type.kind}, Optional: ${property.optional}`);
}
Fazit
deepkit/type ist eine leistungsstarke Bibliothek, die die Lücke zwischen TypeScript-Typen zur Kompilierzeit und der Runtime schließt. Sie eliminiert die Notwendigkeit doppelter Schemata und bietet eine umfassende Lösung für Validierung, Serialisierung und Metaprogrammierung. Für Entwickler, die typsichere Anwendungen auf höchstem Niveau erstellen möchten, ist deepkit/type ein unverzichtbares Werkzeug.
Probieren Sie es in Ihrem nächsten Projekt aus und erleben Sie, wie Runtime-Typen Ihre Entwicklung vereinfachen!
Auch in der Bibliothek
Jetpack Compose für Kotlin: Vollständiger Leitfaden mit Beispielen
Arbeit mit S3 und Cloud-Speichern in JavaScript (Node.js) — die Bibliothek @aws-sdk/client-s3
Rate Limiting in Node.js: Vollständiger Leitfaden zum Schutz von APIs und Lastmanagement