# Getting Started with Typia

[Typia](https://typia.io/) is a TypeScript validation library that transforms your TypeScript types into super-fast validation functions. 

Instead of writing separate schemas like other validation libraries, Typia reads your existing TypeScript types and creates optimized validation code at compile time.

This guide will show you how to use Typia in your TypeScript projects. You'll learn how to set it up, create validation functions, handle errors, and integrate it with web frameworks. 

Let's get started!

[ad-logs]

## Prerequisites

Before you start with Typia, make sure you have a recent version of [Node.js](https://nodejs.org/en/download/) and `npm` installed. You should also know [TypeScript basics](https://www.typescriptlang.org/docs/) since Typia only works with TypeScript projects.


## Setting up the project environment

Setting up Typia is significantly easier as it includes an automated setup wizard. The wizard handles all configuration for you, so you don't need to edit configuration files or manually install dependencies.

Create a new directory and navigate into it:

```command
mkdir typia-validation && cd typia-validation
```

Initialize your project:

```command
npm init -y
```

Install Typia and run the automated setup:

```command
npm install typia
```
```command
npx typia setup
```
```text
[output]
----------------------------------------
 Typia Setup Wizard
----------------------------------------
? Package Manager npm


$ npm i -D typescript@~5.8.3

...
$ npm i -D ts-patch@latest

...
$ npx tsc --init

Created a new tsconfig.json with:                                                                                       
                                                                                                                     TS 
  target: es2016
  module: commonjs
  strict: true
  esModuleInterop: true
  skipLibCheck: true
  forceConsistentCasingInFileNames: true


You can learn more at https://aka.ms/tsconfig

$ npm run prepare

> typia-validation@1.0.0 prepare
> ts-patch install

[+] ts-patch installed!
```

The setup wizard automatically handles everything for you:

- Installs required dependencies (`typescript`, `ts-patch`)
- Configures your `tsconfig.json` with the right settings
- Sets up the transformer plugin
- Adds the necessary npm scripts


That's it! Typia can now transform your TypeScript types into optimized validation functions during code compilation.

## Understanding Typia's fundamentals

Typia works differently from other validation libraries. Instead of defining schemas, you just use regular TypeScript interfaces and types. Typia reads these types when you compile your code and generates super-fast validation functions.

Create a `validation.ts` file in your project:

```typescript
[label validation.ts]
import typia from "typia";

interface User {
  name: string;
  age: number;
  email: string;
}

export const validateUser = typia.createValidate<User>();
export const checkUser = typia.createIs<User>();
```

This code defines a simple `User` interface and creates two validation functions:

- `validateUser`: Returns detailed results with error information if validation fails
- `checkUser`: Returns `true` or `false` to tell you if the data is valid

Now create an `index.ts` file to test these validators:

```typescript
[label index.ts]
import { validateUser, checkUser } from './validation';

const userData = {
  name: 'Alice',
  age: 25,
  email: 'alice@example.com',
};

// Simple boolean check
const isValid = checkUser(userData);
console.log('Is valid:', isValid);

// Detailed validation with error info
const validationResult = validateUser(userData);
if (validationResult.success) {
  console.log('Valid user data:', validationResult.data);
} else {
  console.error('Validation errors:', validationResult.errors);
}
```

The `checkUser` function gives you a simple yes/no answer. The `validateUser` function gives you detailed information. When the data matches your `User` interface, `validateUser` returns a success object with the validated data. When validation fails, it returns specific error information showing exactly what went wrong.

Add the build script to your `package.json`:

```text
[label package.json]
{
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "prepare": "ts-patch install",
[highlight]
    "build": "tsc"
[/highlight]
  }
}
```

Compile and run the application:

```command
npm run build
```
```command
node index.js
```

With valid input data, you'll see:

```text
[output]
Is valid: true
Valid user data: { name: 'Alice', age: 25, email: 'alice@example.com' }
```

Here's what makes Typia helpful: when you compile your code, Typia transforms your validation functions into highly optimized JavaScript. The `typia.createIs<User>()` call becomes a specific function that directly checks for string and number types without any runtime overhead.

## Validation with special tags

Typia lets you add validation rules that go beyond basic type checking. You do this using special tags that work with TypeScript's intersection types. These tags let you express complex validation logic while keeping your code type-safe.

### Adding validation constraints

You can add specific validation rules using Typia's built-in tags. Update your `validation.ts` file:

```typescript
[label validation.ts]
import typia, { tags } from "typia";

interface User {
  name: string & tags.MinLength<3> & tags.MaxLength<50>;
  age: number & tags.Type<"uint32"> & tags.ExclusiveMinimum<18> & tags.Maximum<120>;
  email: string & tags.Format<"email">;
  password: string & tags.MinLength<8> & tags.Pattern<"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).+$">;
}

export const validateUser = typia.createValidate<User>();
```

Each tag adds a specific rule:

- `tags.MinLength<3>` and `tags.MaxLength<50>`: The name must be between 3 and 50 characters
- `tags.Type<"uint32">`: The age must be a positive integer within 32-bit range
- `tags.ExclusiveMinimum<18>`: The age must be greater than 18 (not equal to 18)
- `tags.Format<"email">`: The email must be in valid email format
- `tags.Pattern<"...">`: The password must match the regex pattern (requires numbers, lowercase, and uppercase letters)

Test these rules with invalid data in your `index.ts`:

```typescript
[label index.ts]
import { validateUser } from "./validation";

const invalidUserData = {
  name: "Al", // Too short
  age: 17, // Too young
  email: "not-an-email", // Invalid format
  password: "weak", // Too simple
};

const result = validateUser(invalidUserData);

if (!result.success) {
  console.error("Validation errors:");
  result.errors.forEach((error) => {
    console.log(`  ${error.path}: ${error.expected}`);
  });
}
```

With the invalid data in place, run the script:

```command
npm run build
```
```command
node index.js
```


Running this code shows you specific error messages:

```text
[output]

Validation errors:
  $input.name: string & MinLength<3>
  $input.age: number & ExclusiveMinimum<18>
  $input.email: string & Format<"email">
  $input.password: string & MinLength<8>
```

Typia's error reporting tells you exactly which fields failed and why, making it easy to fix problems or show helpful error messages to users.


When you need validation rules that aren't built into Typia, you can create custom tags using the `tags.TagBase` interface:

```typescript
import typia, { tags } from "typia";

// Custom tag for currency validation
type Currency = tags.TagBase<{
  kind: "currency";
  target: "string";
  value: undefined;
  validate: `$input.match(/^\\$\\d+(\\.\\d{2})?$/) !== null`;
}>;

// Custom tag for even numbers
type EvenNumber = tags.TagBase<{
  kind: "even";
  target: "number";
  value: undefined;
  validate: `$input % 2 === 0`;
}>;

interface Product {
  name: string & tags.MinLength<1>;
  price: string & Currency;
  quantity: number & tags.Type<"uint32"> & EvenNumber;
}

export const validateProduct = typia.createValidate<Product>();
```

Custom tags work by defining JavaScript code in the `validate` property. Typia injects this code into the generated validation function. The `$input` variable represents the value being checked, and your validation code should return `true` for valid values or `false` for invalid ones.

### Combining multiple validation rules

Typia does well at combining multiple validation rules into comprehensive type definitions. You can create complex validation schemas by chaining tags together:

```typescript
interface BlogPost {
  title: string & tags.MinLength<5> & tags.MaxLength<200>;
  content: string & tags.MinLength<100>;
  tags: Array<string & tags.MinLength<2> & tags.MaxLength<20>> & tags.MinItems<1> & tags.MaxItems<10>;
  publishedAt: string & tags.Format<"date-time">;
  status: "draft" | "published" | "archived";
  metadata: {
    author: string & tags.Format<"uuid">;
    category: string & tags.Pattern<"^[a-z-]+$">;
    readingTime: number & tags.Type<"uint32"> & tags.Minimum<1>;
  };
}
```

This schema shows how Typia handles nested objects, arrays with item constraints, union types, and complex validation combinations. The validation function checks every constraint efficiently while providing detailed error information when validation fails.

## Integrating Typia with Express

Typia fits naturally into backend frameworks like Express, where validating request bodies is a common task. You can use Typia to validate incoming data before your route handlers process it, ensuring type safety from the API boundary all the way through your application.


Start by installing Express and its TypeScript types:

```command
npm install express
```
```command
npm install --save-dev @types/express@4 @types/node
```

Let's use our existing `User` interface from the validation file. Make sure your `validation.ts` looks like this:

```typescript
[label validation.ts]
import typia from "typia";

interface User {
  name: string;
  age: number;
  email: string;
}

export const validateUser = typia.createValidate<User>();
```

Now create a basic server in a new file called `server.ts`:

```typescript
[label server.ts]
import express from "express";
import { validateUser } from "./validation";

const app = express();
app.use(express.json());

app.post("/users", (req, res) => {
  console.log("Received request body:", req.body);
  
  const result = validateUser(req.body);

  if (!result.success) {
    console.log("Validation failed");
    return res.status(400).json({
      message: "Validation failed",
      errors: result.errors.map((e) => ({
        field: e.path.replace("$input.", ""),
        expected: e.expected,
        received: e.value,
      })),
    });
  }

  console.log("Validation successful");
  res.status(201).json({
    message: "User created successfully",
    data: result.data,
  });
});

app.listen(3000, () => {
  console.log("Server running on http://localhost:3000");
});
```

In this example, Typia validates the incoming JSON against the `User` interface. If the data is invalid, the API responds with clear error messages. If validation passes, it proceeds with the validated data.


Build and run the server:

```command
npm run build
```
```command
node server.js
```

You should see:

```text
[output]
Server running on http://localhost:3000
```

Now test the API with valid data using curl (in a new terminal):

```command
curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice", "age": 30, "email": "alice@example.com"}'
```

Or use Postman:

![Postman success screenshot](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/d20fae6e-4231-4467-79c4-c4c44318ee00/lg2x =3248x1998)

You'll get a success response:

```json
[output]
{
  "message": "User created successfully",
  "data": {
    "name": "Alice",
    "age": 30,
    "email": "alice@example.com"
  }
}
```


Now test with invalid data to see how Typia handles validation errors:

```command
curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Bob", "age": "twenty-five", "email": 12345}'
```

Or in Postman:

![Postman error screenshot](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/357d47c7-846d-42c2-a20b-b65a47b9f500/md1x =3248x1998)

You'll get a validation error response:

```json
[output]
{
  "message": "Validation failed",
  "errors": [
    {
      "field": "age",
      "expected": "number",
      "received": "twenty-five"
    },
    {
      "field": "email", 
      "expected": "string",
      "received": 12345
    }
  ]
}
```

The server console will show:

```text
[output]
Received request body: { name: 'Bob', age: 'twenty-five', email: 12345 }
Validation failed
```

Typia makes it clear where the data doesn’t match the expected type, helping you catch issues early and respond with helpful errors.


## Final thoughts
Typia helps you validate data using your existing TypeScript types. It keeps your code simple, boosts performance by generating optimized validation functions at build time, and provides detailed error messages when something doesn’t match.

You can learn more in the [Typia documentation](https://typia.io/docs) or explore the source on [GitHub](https://github.com/samchon/typia).