Data Validation in TypeScript: From Theory to Practice
One of the key problems in TypeScript development is the gap between static typing and real data coming from external sources (APIs, forms, localStorage). TypeScript checks types at compile time, but types disappear at runtime. Data validation is the process of checking data against specific rules at runtime, which is critical for application reliability.
In this article, we will explore popular libraries for data validation in TypeScript: Zod, Yup, Joi, and class-validator. We'll look at their features, usage examples, and help you choose the right tool for your project.
Why is TypeScript Alone Not Enough?
TypeScript is a developer tool. It helps write safer code but does not protect against:
- Incorrect data from APIs (the
agefield might come as a string"25") - Missing required fields
- Incorrect formats (email, URL, phone number)
- Values exceeding allowed ranges
Runtime data validation solves these problems by checking data against a schema and providing clear error messages.
Zod — The Modern Standard
Zod is the most popular library for validation in TypeScript. Its main advantage is tight integration with the type system: you can automatically infer a type from a schema.
Installation
npm install zodUsage Example
import { z } from 'zod';
// Define a schemaconst UserSchema = z.object({ id: z.number().positive(), email: z.string().email(), age: z.number().min(18).max(120).optional(), role: z.enum(['admin', 'user', 'guest']),});
// Infer the type from the schematype User = z.infer<typeof UserSchema>;
// Validationconst result = UserSchema.safeParse({ id: 1, email: 'user@example.com', age: 25, role: 'admin',});
if (result.success) { // result.data — valid data with type User console.log(result.data.email);} else { // result.error — detailed error information console.log(result.error.format());}Key features of Zod:
- Automatic type inference via
z.infer - Data transformation (e.g., converting strings to numbers)
- Validation of nested objects and arrays
- Support for unions, intersections, discriminated unions
- Refinement — custom checks
Yup — Battle-Tested
Yup is a library from the creators of Formik. It is ideal for form validation in React. Yup has a more declarative syntax and a rich ecosystem.
Example
import * as yup from 'yup';
const schema = yup.object().shape({ name: yup.string().required('Name is required'), email: yup.string().email('Invalid email').required(), age: yup.number().positive().integer().min(18, 'Age must be at least 18'), tags: yup.array().of(yup.string()).min(1, 'Select at least one tag'),});
schema.validate({ name: 'Ivan', email: 'ivan@example.com', age: 25, tags: ['typescript'],}).then(validData => { console.log('Data is valid:', validData);}).catch(err => { console.log('Error:', err.errors);});Features of Yup:
- Localization of error messages
- Lazy validation
- Value transformation (cast)
- Built-in integration with Formik
Joi — Powerful and Strict
Joi is a library with a vast set of validators. It was originally created for Node.js (Hapi.js) but works great with TypeScript as well.
<
Also in library
PDF Generation in JavaScript (Node.js): Libraries and Tools for Creating PDF
Parsing HTML in Node.js: TOP Libraries and Code Examples
Logging in Rust: Overview of the Best Libraries and Solutions for Your Project
Cryptography in Kotlin: Encryption and Hashing
Monitoring C++ Applications: metrics Library for Collecting Metrics