RunTypes

Supported Types

Comprehensive list of supported TypeScript types and feature comparison with other validation libraries.

@mionjs/run-types supports a comprehensive set of TypeScript types.
The long term goal is to fully support all typescript features for full compatibility.

Type Support Comparison

Type CategoryTyperun-typesZodTypiaAJVTypeBox
Primitivesstring✅✅✅✅✅
number✅✅✅✅✅
boolean✅✅✅✅✅
bigint✅✅✅❌✅
symbol✅✅✅❌✅
null✅✅✅✅✅
undefined✅✅✅❌✅
void✅✅✅❌✅
never✅✅✅❌✅
any✅✅✅✅✅
unknown✅✅✅✅✅
LiteralsString literals✅✅✅✅✅
Number literals✅✅✅✅✅
Boolean literals✅✅✅✅✅
Template literals✅❌✅❌✅
Objectsinterface✅✅✅✅✅
type aliases✅✅✅✅✅
class✅❌✅❌❌
Nested objects✅✅✅✅✅
Optional properties✅✅✅✅✅
Readonly properties✅✅✅❌✅
Index signatures✅✅✅✅✅
CollectionsArray<T>✅✅✅✅✅
Tuple✅✅✅✅✅
Record<K, V>✅✅✅✅✅
Native ObjectsDate✅✅✅❌✅
RegExp✅❌✅❌❌
Map<K, V>✅✅✅❌❌
Set<T>✅✅✅❌❌
EnumsNumeric enums✅✅✅❌❌
String enums✅✅✅❌❌
Const enums✅❌✅❌❌
Unions & IntersectionsUnion types✅✅✅✅✅
Discriminated unions🚀✅✅✅✅
Intersection types✅✅✅✅✅
Utility TypesPartial<T>✅✅✅❌✅
Required<T>✅✅✅❌✅
Pick<T, K>✅✅✅❌✅
Omit<T, K>✅✅✅❌✅
Exclude<T, U>✅❌✅❌✅
Extract<T, U>✅❌✅❌✅
NonNullable<T>✅✅✅❌❌
Awaited<T>✅❌✅❌✅
Parameters<F>✅❌✅❌✅
ReturnType<F>✅❌✅❌✅
String UtilitiesUppercase<S>⚠️❌✅❌✅
Lowercase<S>⚠️❌✅❌✅
Capitalize<S>⚠️❌✅❌✅
Uncapitalize<S>❌❌✅❌✅
FunctionsFunction types💎✅✅❌✅
Method signatures✅❌✅❌❌
Call signatures✅❌✅❌❌
Rest parameters✅✅✅❌✅
AdvancedCircular references✅❌✅❌⚠️
Generic types✅✅✅❌✅
Conditional types⚠️❌✅❌⚠️
Mapped types❌❌✅❌❌
Type inference❌❌x❌❌
⚠️ = Partial support with limitations
🚀 = mion has optimized type checking for discriminated unions.
💎 = mion is the only framework from the table that can extract types directly from functions
import {reflectFunction} from '@mionjs/run-types';

function sayHello(name: string): string {
    return `Hello ${name}`;
}

const fnType = reflectFunction(sayHello);
// fnType = FunctionRunType<type (name: string) => string>

Feature Comparison

Featurerun-typesZodTypiaAJVTypeBox
Core
Type inference from TS✅❌✅❌❌
Schema-first approach❌✅❌✅✅
JIT compilation✅❌AOT✅✅
TSC build required✅❌✅❌❌
Validation
Type validation✅✅✅✅✅
Strict validation✅✅✅✅✅
Error messages✅✅✅✅✅
Custom error messages✅✅✅✅✅
Serialization
JSON serialization✅❌✅❌❌
Binary serialization✅❌PROTOBUF❌❌
Date handling✅❌✅❌✅
BigInt handling✅❌✅❌✅
Map/Set handling✅❌✅❌❌
Other
Mock data generation✅❌✅❌❌
Function reflection✅❌❌❌❌
AOT code generation✅❌✅❌✅

Approach Comparison

Schema-First (Zod, AJV)

With schema-first libraries, you define schemas separately from your TypeScript types:

import {z} from 'zod';

// Zod example - schema is source of truth
const UserSchema = z.object({
    name: z.string(),
    age: z.number(),
    email: z.string().email(),
});
type User = z.infer<typeof UserSchema>;

Pros: No build step, works everywhere Cons: Duplicate definitions, schemas can drift from actual types

Type-First (run-types, Typia)

With type-first libraries, TypeScript types are the source of truth:

import {createIsTypeFn} from '@mionjs/run-types';
import {FormatEmail} from '@mionjs/type-formats/StringFormats';

// run-types example - TypeScript is source of truth
interface User {
    name: string;
    age: number;
    email: FormatEmail; // Using type formats for validation
}

const validate = await createIsTypeFn<User>();

Pros: Single source of truth, no schema duplication Cons: Requires TypeScript compiler integration

run-types vs Typia: Function Reflection

The key difference between run-types and Typia is function reflection. While both are type-first, Typia cannot extract types directly from function signatures, requiring you to declare types separately and pass them as generic parameters.

Typia + Hono example: (required to create validators manually)

import {Hono} from 'hono';
import {typiaValidator} from '@hono/typia-validator';
import typia from 'typia';

interface IBbsArticle {
    // ❌ Must declare type separately
    id: string;
    title: string;
    body: string;
    created_at: string;
}

// ❌ Must create validator with explicit generic type
const validate = typia.createValidate<IBbsArticle>();

const app = new Hono();

app.post(
    '/',
    typiaValidator('json', validate), // ❌ Pass validator as middleware
    (c) => {
        const data = c.req.valid('json');
        return c.json({id: data.id, title: data.title, body: data.body});
    }
);

mion example (types extracted from functions and validated automatically):

import {Routes, route} from '@mionjs/router';

interface Article {
    id: string;
    title: string;
    body: string;
}

type NewArticle = Omit<Article, 'id'>;

declare function generateId(): string;

// ✅ Types are extracted directly from the function signature
const routes = {
    createArticle: route((ctx, article: NewArticle): Article => {
        return {id: generateId(), ...article};
    }),
} satisfies Routes;

With mion, the router automatically extracts parameter and return types from your route handlers — no separate type declarations, no generic parameters, no middleware wiring, and no risk of types drifting out of sync.


When to Use run-types

✅ Use run-types when:

  • You want TypeScript types as the single source of truth
  • You need JSON serialization with complex types (Date, Map, Set, BigInt)
  • You need binary serialization for performance
  • You want mock data generation from types
  • You're building APIs with mion

❌ Consider alternatives when:

  • You need to share schemas with non-TypeScript consumers
  • You're building a library consumed by vanilla JavaScript
  • You need schemas defined at runtime

at runtime

Copyright © 2026