deepkit/type para TypeScript: guía completa con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

deepkit/type para TypeScript: guía completa con ejemplos

En el mundo de TypeScript existe un problema fundamental: los tipos solo existen en tiempo de compilación. Después de la transpilación a JavaScript, toda la información sobre los tipos desaparece. Esto hace imposible la validación en tiempo de ejecución, la serialización dinámica o la construcción de sistemas complejos que dependan de metadatos de tipos. La librería deepkit/type resuelve este problema de forma radical: traslada el sistema de tipos de TypeScript al runtime, permitiendo trabajar con los tipos como si fueran datos.

El valor principal de deepkit/type es que no requiere escribir esquemas duplicados (como en Zod o Yup). Tú describes los tipos una sola vez —en TypeScript puro— y la librería los extrae automáticamente en tiempo de ejecución. Esto permite realizar validación de datos, serialización/deserialización, reflexión (obtener información sobre propiedades, genéricos, decoradores) e incluso generar código basado en tipos. deepkit/type no es solo un validador, sino un framework completo para metaprogramación.

La librería es ideal para proyectos donde la tipificación estricta es importante en todos los niveles: servidores API (validación de solicitudes entrantes), bases de datos (mapeo de tipos a SQL), archivos de configuración, sistemas RPC y herramientas de generación de código. Gracias a su integración con deepkit/framework, también se usa para crear aplicaciones de servidor de alto rendimiento con validación y serialización automáticas.

Instalación

deepkit/type es un paquete npm para TypeScript. La instalación se realiza con el comando estándar:

npm install @deepkit/type reflect-metadata

También necesitarás configurar tu tsconfig.json para soportar decoradores y emitir metadatos:

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "strict": true,
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "./dist"
  }
}

Si usas ts-node para ejecutar, asegúrate de que cargue reflect-metadata primero. Agrega al inicio de tu archivo de entrada:

import 'reflect-metadata';

Inicio rápido

Un ejemplo mínimo demuestra cómo declarar un tipo y obtener su representación en runtime:

import 'reflect-metadata';
import { typeOf, ReflectionClass } from '@deepkit/type';

// Declaramos una interfaz
interface User {
  id: number;
  name: string;
  email?: string;
}

// Obtenemos el tipo en runtime
const userType = typeOf();
console.log(userType); // ReflectionClass

// Verificamos las propiedades
const reflection = ReflectionClass.from(userType);
console.log(reflection.getProperty('name').type); // ReflectionProperty
console.log(reflection.getProperty('id').type.kind); // 'number'

Este código mostrará información sobre el tipo User en la consola. Nota: no escribimos ningún esquema —solo una interfaz TypeScript pura.

Métodos y funciones principales

A continuación se presentan las capacidades clave de deepkit/type. Para cada método se indica la firma, una breve descripción y un ejemplo funcional.

1. typeOf

Firma: typeOf<T>(): ReflectionClass

Qué hace: Extrae la representación en runtime del tipo T. Devuelve un objeto ReflectionClass que contiene información completa sobre la estructura del tipo: propiedades, sus tipos, modificadores (optional, readonly), genéricos y decoradores.

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

Firma: is<T>(value: unknown): value is T

Qué hace: Valida si un valor desconocido coincide con el tipo T en tiempo de ejecución. Actúa como un guardia de tipo (type guard) de TypeScript, devolviendo true si el valor es válido y false en caso contrario.

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

interface User {
  id: number;
  name: string;
  email?: string;
}

const data: unknown = { id: 1, name: 'Ana' };

if (is(data)) {
  console.log(data.name); // TypeScript sabe que 'data' es User aquí
} else {
  console.log('Datos inválidos');
}

3. cast

Firma: cast<T>(value: unknown): T

Qué hace: Convierte (hace cast) de un valor desconocido al tipo T, lanzando una excepción si la conversión falla. Útil para deserializar datos de APIs o archivos JSON de forma segura.

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

interface Config {
  port: number;
  host: string;
  debug: boolean;
}

const rawData = JSON.parse('{"port": 3000, "host": "localhost", "debug": true}');
const config = cast(rawData);
console.log(config.port); // 3000

4. serialize

Firma: serialize<T>(value: T): any

Qué hace: Serializa un objeto tipado a un formato plano (JSON-compatible). Respeta decoradores y reglas de transformación definidas en el tipo.

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

class User {
  id: number = 0;
  name: string = '';
  @hidden // decorador para ocultar este campo
  password: string = '';
}

const user = new User();
user.id = 1;
user.name = 'Carlos';
user.password = 'secreto';

const serialized = serialize(user);
console.log(serialized); // { id: 1, name: 'Carlos' } - password oculto

5. deserialize

Firma: deserialize<T>(value: any): T

Qué hace: Deserializa un objeto plano (por ejemplo, de JSON) a una instancia tipada de la clase T. Aplica validación y transformaciones automáticamente.

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

class Product {
  id: number = 0;
  title: string = '';
  price: number = 0;
}

const raw = { id: 1, title: 'Laptop', price: 999.99 };
const product = deserialize(raw);
console.log(product instanceof Product); // true
console.log(product.title); // 'Laptop'

6. ReflectionClass

Firma: ReflectionClass.from(type: ReflectionClass): ReflectionClass

Qué hace: Proporciona una API completa para inspeccionar tipos en runtime. Permite obtener propiedades, métodos, decoradores, genéricos y más. Es la base para la metaprogramación con deepkit/type.

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

interface Task {
  id: number;
  title: string;
  completed: boolean;
}

const taskType = typeOf();
const reflection = ReflectionClass.from(taskType);

// Listar todas las propiedades
for (const prop of reflection.getProperties()) {
  console.log(`${prop.name}: ${prop.type.kind}`);
}
// id: number
// title: string
// completed: boolean

Conclusión

deepkit/type transforma la forma en que trabajamos con tipos en TypeScript, llevando la seguridad de tipos al runtime sin necesidad de esquemas duplicados. Con métodos como typeOf, is, cast, serialize y deserialize, puedes validar, transformar e inspeccionar datos de manera eficiente. Es una herramienta imprescindible para proyectos que requieren tipificación estricta en todos los niveles, desde APIs hasta bases de datos.

¿Listo para probarlo? Instala deepkit/type hoy y descubre el poder de los tipos en runtime con TypeScript.

Recommendations