ReliantType
TypeScript Schema Validation with Interface-Like Syntax
A modern TypeScript validation library designed around familiar interface syntax and powerful conditional validation. Experience schema validation that feels natural to TypeScript developers while unlocking advanced runtime validation capabilities.
Formerly Fortify Schema - Originally developed at github.com/Nehonix-Team/fortify-schema
Migration Notice: The fortify-schema package will be deprecated in favor of reliant-type. While fortify-schema will continue to receive critical security updates, new features and improvements will only be available in reliant-type. We recommend migrating to reliant-type for the best experience and ongoing support.
New Features
- Function Types: Define strict contracts for functions with
fn(...)syntax, enforcing argument types and return values at runtime. - Required Fields: Enforce non-empty strings and non-zero numbers with
"string!"and"number!". - Object Types: Validate generic object structures with
"object"and"object?". - Enhanced Security: All string operations now use secure regex patterns.
- Improved Performance: Optimized validation paths with better caching and precompilation.
- Better Error Messages: More descriptive validation errors with clear property paths.
Quick Start
npm install reliant-typeimport { Interface } from "reliant-type";
// Define schemas with familiar TypeScript-like syntax
const UserSchema = Interface({
id: "uuid",
email: "email!", // Required (non-empty) email
name: "string(2,50)!", // Required string with length constraints
age: "number(18,120)?",
role: "admin|user|guest",
// Function validation
onUpdate: "fn((status: string) => boolean)",
// Object and array types
profile: "object", // Any object structure
tags: "string[]", // Array of strings
metadata: "record<string, any>", // Dynamic key-value pairs
// Advanced conditional validation based on runtime properties
permissions: "when config.hasPermissions.$exists() *? string[] : =[]",
adminTools: "when role=admin *? boolean : =false",
});
// Validate with complete TypeScript inference
const result = UserSchema.safeParse(userData);
if (result.success) {
console.log("Valid user:", result.data); // Fully typed!
} else {
console.log("Validation errors:", result.errors);
}Note: For nested objects, we recommend limiting depth to 50-100 or no more than 300 levels for performance and safety. Default depth limit is 500.
Test by running:
bun src/__tests__/test_nested_obj.ts(requires bun:npm i -g bun)npm run benchmark:nestedObject(requires tsx:npm i -g tsx)
Table of Contents
- Installation & Setup
- Core Features
- Function Types
- Utility Functions
- Conditional Validation
- Live Utility - Real-time Validation
- Real-World Applications
- Performance Excellence
- Advanced Capabilities
- Developer Experience
- API Reference
Installation & Setup
Requirements
- TypeScript 4.5+
- Node.js 14+
- VS Code (recommended for enhanced development experience)
Installation
# NPM
npm install reliant-type
# Yarn
yarn add reliant-type
# PNPM
pnpm add reliant-type
# Bun
bun add reliant-typeVS Code Extension
Enhance your development workflow with our dedicated VS Code extension featuring comprehensive developer tools:
Enhanced Features
- Syntax Highlighting: Full syntax highlighting for all Reliant Type types and utilities.
- Hover Documentation: Detailed type information, examples, and use cases on hover.
- Go-to-Definition: Ctrl+Click on types to open comprehensive documentation.
- IntelliSense Support: Smart autocomplete for schema definitions.
- Error Detection: Real-time validation of schema syntax.
- Code Snippets: Pre-built templates for common schema patterns.
Interactive Documentation
When you hover over any type in Interface({...}) blocks, you'll see:
- Type Description: What the type validates.
- Usage Examples:
"string","string?","string[]". - Use Cases: When and where to use each type.
- Code Examples: Complete working examples.
Installation
# Download and install
curl https://sdk.nehonix.com/pkgs/mods/vscode/latest/reliant-type.vsix -o reliant-type.vsix
code --install-extension reliant-type.vsix
# Or just search for "reliant-type" in the vscode marketplaceCore Features
Intuitive Schema Definition
import { Interface } from "reliant-type";
const ProductSchema = Interface({
id: "uuid",
name: "string(1,100)",
price: "number(0.01,99999.99)",
category: "electronics|books|clothing|home",
inStock: "boolean",
tags: "string[]?",
description: "string(,500)?",
createdAt: "date",
});
// Usage with full type safety
const product = {
id: "123e4567-e89b-12d3-a456-426614174000",
name: "Wireless Headphones",
price: 99.99,
category: "electronics",
inStock: true,
tags: ["wireless", "audio", "bluetooth"],
createdAt: new Date(),
};
const result = ProductSchema.safeParse(product);
console.log(result.success); // true
console.log(result.data); // Fully typed product dataComprehensive Type Support
const ComprehensiveSchema = Interface({
// Fundamental types
name: "string",
age: "number",
active: "boolean",
birthday: "date",
// Optional fields
nickname: "string?",
bio: "string?",
// Required fields (cannot be empty/zero)
requiredName: "string!", // Non-empty string required
requiredCount: "number!", // Non-zero number required
// Constraint validation
username: "string(3,20)", // 3-20 characters
password: "string(8,)", // Minimum 8 characters
score: "number(0,100)", // Range 0-100
// Format validation
email: "email",
website: "url",
secureApi: "url.https", // HTTPS-only validation
devServer: "url.dev", // Development mode (allows localhost and security features disabled)
phone: "phone",
userId: "uuid",
// Array validation
tags: "string[]", // Required array
scores: "number[]?", // Optional array
limitedTags: "string[](1,5)", // 1-5 items
// Union types
status: "active|inactive|pending",
role: "user|admin|moderator",
// Object types
profile: "object", // Any object
config: "object?", // Optional object
// Record types (dynamic key-value objects)
settings: "record<string, any>", // String keys, any values
counters: "record<string, number>", // String keys, number values
metadata: "record<string, string>", // String keys, string values
// Literal values
version: "=2.0",
type: "=user",
});Function Types
ReliantType introduces powerful runtime and compile-time validation for function signatures using the fn type. This feature allows you to define strict contracts for functions within your schema.
Syntax
"fn((argument_list) => return_type)";Examples
const ServiceSchema = Interface({
// Basic function: takes string, returns boolean
isValid: "fn((input: string) => boolean)",
// Multiple arguments
add: "fn((a: number, b: number) => number)",
// Optional arguments
log: "fn((message: string, context?: object) => void)",
// Rest parameters (Spread operator)
sum: "fn((...numbers: number[]) => number)",
// Generic placeholder (TYPE = any)
transform: "fn((input: TYPE) => TYPE)",
});Runtime Behavior
When a function defined in a schema is accessed, it is wrapped in a validation proxy that enforces:
- Argument Count: Throws an error if required arguments are missing.
- Argument Types: Throws an error if arguments do not match defined types.
- Return Type: Throws an error if the return value does not match the defined type.
This ensures strict contract adherence during execution.
Technical Limitations
Due to JavaScript's dynamic nature, some validation aspects are deferred:
- Deferred Execution Validation:
safeParseverifies that the field is a function and checks its declared argument count (arity). However, it cannot validate the function's internal logic or return value without executing it.- Implication: A function that returns an invalid type will pass
safeParse, but will throw an error when called.
- Implication: A function that returns an invalid type will pass
- Side Effects: To prevent unintended side effects (e.g., database writes), ReliantType never speculatively executes functions during validation.
- Spread Operator Arity: Functions using spread operators (
...args) have a declared length of 0 in JavaScript. Therefore, ReliantType cannot enforce a minimum argument count atsafeParsetime for these functions; validation occurs strictly at runtime.
Utility Functions
Reliant Type provides powerful utility functions for advanced schema definition:
Make.const() - Constant Values
Create schemas that validate against exact constant values:
import { Interface, Make } from "reliant-type";
const ConfigSchema = Interface({
// Exact string constants
apiVersion: Make.const("v2.1"),
environment: Make.const("production"),
// Numeric constants
maxRetries: Make.const(3),
timeout: Make.const(5000),
// Boolean constants
enableLogging: Make.const(true),
// Complex constants
defaultSettings: Make.const({
theme: "dark",
language: "en",
}),
// Array constants
supportedFormats: Make.const(["json", "xml", "csv"]),
});Record Types - Dynamic Objects
Validate objects with dynamic keys but consistent value types:
const DynamicSchema = Interface({
// String keys with any values
metadata: "record<string, any>",
// String keys with number values (counters, scores, etc.)
scores: "record<string, number>",
// String keys with string values (translations, labels, etc.)
translations: "record<string, string>",
// Optional record types
optionalSettings: "record<string, boolean>?",
});Conditional Validation
Reliant Type's standout feature: advanced conditional validation based on runtime properties and business logic.
const SmartUserSchema = Interface({
// Runtime context objects
config: "any?",
user: "any?",
features: "any?",
// Core user data
id: "uuid",
email: "email",
role: "admin|user|guest",
// Dynamic validation based on runtime state
hasPermissions: "when config.permissions.$exists() *? string[] : =[]",
hasProfile: "when user.profile.$exists() *? boolean : =false",
isListEmpty: "when config.items.$empty() *? boolean : =true",
hasAdminRole: "when user.roles.$contains(admin) *? boolean : =false",
// Smart default values
defaultTags: 'when config.tags.$exists() *? string[] : =["default","user"]',
defaultSettings:
'when config.theme.$exists() *? any : ={"mode":"light","lang":"en"}',
// Deep property access
advancedFeature:
"when user.profile.settings.advanced.$exists() *? boolean : =false",
// Complex business rules
isValidUser:
"when user.email.$exists() && user.verified.$exists() *? boolean : =false",
});Runtime Validation Methods
const RuntimeMethodsSchema = Interface({
data: "any?",
// Property existence checking
hasData: "when data.field.$exists() *? boolean : =false",
// Empty state validation
isEmpty: "when data.list.$empty() *? boolean : =true",
// Null checking
isNull: "when data.value.$null() *? boolean : =false",
// String pattern matching
containsText:
"when data.description.$contains(important) *? boolean : =false",
startsWithPrefix: "when data.code.$startsWith(PRE) *? boolean : =false",
endsWithSuffix: "when data.filename.$endsWith(.pdf) *? boolean : =false",
// Numeric range validation
inRange: "when data.score.$between(0,100) *? boolean : =false",
// Value inclusion testing
isValidStatus:
"when data.status.$in(active,pending,inactive) *? boolean : =false",
});Live Utility - Real-time Validation
The Live utility transforms Reliant Type into a powerful real-time validation system with EventEmitter-like interface, data transformation pipelines, and stream control methods. Perfect for modern applications requiring reactive validation.
Key Features
- Real-time Field Validation: Validate form fields as users type.
- EventEmitter Interface: Full
.on(),.emit(),.off(),.once()support. - Data Transformation Pipeline: Chain
.transform(),.filter(),.map()operations. - Stream Control:
.pause(),.resume(),.destroy()for flow control. - Stream Piping: Connect validators with
.pipe()for complex workflows. - Performance Monitoring: Built-in statistics and performance tracking.
- InterfaceSchema Sync: Perfect synchronization with Interface validation.
Quick Example
import { Live, Interface } from "reliant-type";
const UserSchema = Interface({
name: "string(2,50)",
email: "email",
age: "number(18,120)",
});
// Create stream validator with transformation pipeline
const validator = Live.stream(UserSchema)
.transform((data) => ({ ...data, timestamp: Date.now() }))
.filter((data) => data.age >= 21)
.map((data) => ({ ...data, name: data.name.toUpperCase() }));
// Listen for results
validator.on("valid", (data) => console.log("Valid:", data));
validator.on("invalid", (data, errors) => console.log("Invalid:", errors));
validator.on("filtered", (data) => console.log("Filtered:", data));
// Process data
validator.validate({ name: "john", email: "john@example.com", age: 25 });Real-World Applications
E-Commerce Product Management
const ECommerceProductSchema = Interface({
// Product identification
id: "uuid",
sku: "string(/^[A-Z0-9-]{8,20}$/)",
name: "string(1,200)",
slug: "string(/^[a-z0-9-]+$/)",
// Pricing structure
price: "number(0.01,999999.99)",
compareAtPrice: "number(0.01,999999.99)?",
cost: "number(0,999999.99)?",
// Inventory management
inventory: {
quantity: "number(0,)",
trackQuantity: "boolean",
allowBackorder: "boolean",
lowStockThreshold: "number(0,)?"
},
// Content management
description: "string(,5000)?",
shortDescription: "string(,500)?",
category: "electronics|clothing|books|home|sports|beauty",
tags: "string[](0,20)",
// Media assets
images: {
primary: "url",
gallery: "url[](0,10)",
alt: "string(,100)?"
}?,
// SEO optimization
seo: {
title: "string(,60)?",
description: "string(,160)?",
keywords: "string[](0,10)"
}?,
// Business logic with conditional validation
config: "any?",
// Product type-specific requirements
shipping: "when config.isDigital.$exists() *? any? : ={weight:0,dimensions:{}}",
subscription: "when config.isSubscription.$exists() *? any : =null",
variants: "when config.hasVariants.$exists() *? any[] : =[]",
// Publication workflow
status: "draft|active|archived",
publishedAt: "date?",
createdAt: "date",
updatedAt: "date"
});Performance Excellence
Reliant Type is engineered for high-performance validation with multiple optimization strategies:
Performance Architecture
// Built-in performance optimizations
const performanceFeatures = {
// Schema compilation
precompilation: "Schemas optimized at creation time",
caching: "Intelligent caching for union types and constraints",
// Memory management
memoryOptimized: "Minimal runtime overhead per validation",
zeroAllocation: "Hot paths avoid unnecessary object creation",
// Validation efficiency
earlyTermination: "Fast-fail validation on first error",
typeSpecialization: "Optimized validation paths per data type",
};Benchmark Highlights
Our continuous performance monitoring shows excellent results across all validation scenarios:
- High Throughput: Millions of operations per second for common validation patterns.
- Consistent Performance: Low variation in execution times.
- Memory Efficient: Minimal memory overhead per schema instance.
- Scalable: Performance scales predictably with data complexity.
Advanced Capabilities
Schema Transformation
import { Mod } from "reliant-type";
const BaseUserSchema = Interface({
id: "uuid",
email: "email",
name: "string",
password: "string",
role: "user|admin",
createdAt: "date",
});
// Powerful schema transformations
const PublicUserSchema = Mod.omit(BaseUserSchema, ["password"]);
const PartialUserSchema = Mod.partial(BaseUserSchema);
const RequiredUserSchema = Mod.required(PartialUserSchema);
const ExtendedUserSchema = Mod.extend(BaseUserSchema, {
lastLogin: "date?",
preferences: {
theme: "light|dark",
notifications: "boolean",
},
});Comprehensive Error Handling
const result = UserSchema.safeParse(invalidData);
if (!result.success) {
// Rich error information for debugging
result.errors.forEach((error) => {
console.log(`Field: ${error.path.join(".")}`);
console.log(`Message: ${error.message}`);
console.log(`Code: ${error.code}`);
console.log(`Expected: ${error.expected}`);
console.log(`Received: ${error.received}`);
});
}
// Exception-based validation
try {
const data = UserSchema.parse(userData);
// Process validated data
} catch (error) {
if (error instanceof ValidationError) {
console.log("Validation failed:", error.errors);
}
}Developer Experience
VS Code Extension Features
Our dedicated VS Code extension transforms your development experience:
- Intelligent Syntax Highlighting for schema definitions.
- Advanced IntelliSense with type and method completion.
- Real-time Validation with inline error detection.
- Rich Hover Documentation for all types and methods.
- Multiple Theme Support for different coding preferences.
const UserSchema = Interface({
// IntelliSense provides comprehensive type suggestions
email: "email", // Hover documentation explains validation rules
// Smart constraint completion
name: "string(2,50)", // Auto-suggests constraint syntax patterns
// Conditional method IntelliSense
hasProfile: "when user.profile.$exists() *? boolean : =false",
// ^ Shows all 8 available runtime methods
});What Sets Reliant Type Apart
Design Philosophy
- Developer-Centric: Built around familiar TypeScript patterns and conventions.
- Interface Syntax: Schema definitions that feel like native TypeScript interfaces.
- Conditional Intelligence: Advanced runtime validation based on dynamic properties.
- Performance Focused: Optimized for high-throughput production applications.
- Tooling Excellence: Professional-grade development tools and IDE integration.
- Type Safety: Complete TypeScript inference and compile-time validation.
Key Strengths
- Familiar Syntax: Write schemas using TypeScript-like interface definitions.
- Advanced Conditionals: Unique runtime property validation and business logic.
- Rich Tooling: Dedicated VS Code extension with comprehensive development support.
- Type Integration: Seamless TypeScript integration with full type inference.
- Production Ready: Battle-tested with comprehensive error handling and debugging.
Community and Growth
We're building Reliant Type with transparency and community feedback at its core. We welcome:
- Real-world usage feedback and performance insights.
- Issue reports with detailed reproduction cases.
- Feature requests based on practical development needs.
- Performance benchmarking on diverse use cases.
- Constructive feedback on API design and developer experience.
API Reference
Core Validation Methods
Interface(schema, options?)
Creates a new schema instance with comprehensive validation rules.
const UserSchema = Interface(
{
id: "uuid",
name: "string",
},
{
strict: true, // Reject extra properties
loose: false, // Disable automatic type coercion
allowUnknown: false, // Reject unknown properties
}
);schema.parse(data)
Synchronous validation that returns validated data or throws detailed errors.
try {
const user = UserSchema.parse(userData);
// user is fully typed and validated
} catch (error) {
console.error(error.errors);
}schema.safeParse(data)
Safe validation that returns a result object without throwing exceptions.
const result = UserSchema.safeParse(userData);
if (result.success) {
console.log(result.data); // Fully typed and validated
} else {
console.error(result.errors); // Detailed validation errors
}schema.safeParseUnknown(data)
Safe validation for unknown data types, ideal for testing and debugging.
const result = UserSchema.safeParseUnknown(unknownData);
// Same return type as safeParse() but accepts any input typeschema.parseAsync(data)
Asynchronous validation with promise-based error handling.
try {
const user = await UserSchema.parseAsync(userData);
console.log("Valid user:", user);
} catch (error) {
console.error("Validation failed:", error.message);
}schema.safeParseAsync(data)
Asynchronous safe validation that never throws exceptions.
const result = await UserSchema.safeParseAsync(userData);
if (result.success) {
console.log("Valid user:", result.data);
} else {
console.error("Validation errors:", result.errors);
}schema.safeParseUnknownAsync(data)
Asynchronous safe validation for unknown data types.