> ## Documentation Index
> Fetch the complete documentation index at: https://ilanaorm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript

> Auto-generate TypeScript types from your models and migrations

## Overview

IlanaORM generates TypeScript types directly from your model files and migration definitions — no build step, no schema file, no manual maintenance.

Each model gets:

* A typed `Attributes` interface with the correct type per column (including enum union types)
* A `declare class` with relation method signatures
* A barrel `index.d.ts` for clean imports

## Generating Types

```bash theme={null}
npx ilana types
```

Types are written to a `types/` directory by default:

```
types/
  User.d.ts
  Post.d.ts
  Comment.d.ts
  index.d.ts
```

### Custom output directory

```bash theme={null}
npx ilana types --out=src/types
```

### Auto-generation on migrate

Types are regenerated automatically every time you run a migration:

```bash theme={null}
npx ilana migrate      # runs migration + regenerates types
npx ilana migrate:rollback  # rolls back + regenerates types
```

## Example Output

Given this model and migration:

```javascript theme={null}
// models/User.js
export default class User extends Model {
  static table = 'users';
  static softDeletes = true;
  static fillable = ['name', 'email', 'role'];
  static casts = { preferences: 'json' };

  static { this.register(); }

  posts() { return this.hasMany('Post', 'user_id'); }
}
```

```javascript theme={null}
// migrations/create_users_table.js
table.increments('id');
table.string('name').notNullable();
table.string('email').notNullable();
table.enum('role', ['user', 'admin', 'moderator']).defaultTo('user');
table.json('preferences').nullable();
table.timestamps(true, true);
table.timestamp('deleted_at').nullable();
```

IlanaORM generates:

```typescript theme={null}
// types/User.d.ts — auto-generated by `npx ilana types` — do not edit manually
import { Model, HasMany } from 'ilana-orm';
import type { Post } from './index';

export interface UserAttributes {
  id: number;
  name?: string;
  email?: string;
  role?: 'user' | 'admin' | 'moderator';  // ← union type from enum values
  preferences?: Record<string, any> | null;
  created_at?: Date;
  updated_at?: Date;
  deleted_at?: Date | null;
  posts?: Post[];
}

declare class User extends Model<UserAttributes> {
  posts(): HasMany;
}

export default User;
```

```typescript theme={null}
// types/index.d.ts
export { default as User, type UserAttributes } from './User';
export { default as Post, type PostAttributes } from './Post';
```

## Using the Generated Types

```typescript theme={null}
import type { UserAttributes } from './types';
import User from './models/User';

// Attributes interface for type-safe objects
const data: UserAttributes = {
  name: 'Alice',
  email: 'alice@example.com',
  role: 'admin', // ✓ — TypeScript validates against 'user' | 'admin' | 'moderator'
};

// Model instance is fully typed
const user = await User.find(1);
user.name;    // string | undefined
user.role;    // 'user' | 'admin' | 'moderator' | undefined
user.posts;   // Post[] | undefined (if eager loaded)
```

## What Gets Inferred

| Source                                    | What it generates                             |
| ----------------------------------------- | --------------------------------------------- |
| Migration `string`, `text`                | `string`                                      |
| Migration `integer`, `float`, `decimal`   | `number`                                      |
| Migration `boolean`                       | `boolean`                                     |
| Migration `date`, `datetime`, `timestamp` | `Date`                                        |
| Migration `json`, `jsonb`                 | `Record<string, any>`                         |
| Migration `enum('col', ['a','b'])`        | `'a' \| 'b'`                                  |
| `static casts = { col: 'json' }`          | `Record<string, any>`                         |
| `static casts = { col: 'array' }`         | `any[]`                                       |
| `static casts = { col: 'boolean' }`       | `boolean`                                     |
| `.nullable()` in migration                | `Type \| null`                                |
| `static softDeletes = true`               | adds `deleted_at?: Date \| null`              |
| Relation methods                          | typed return (`Post[]`, `User \| null`, etc.) |

## Notes

* Types are only generated for **TypeScript projects** (detected by the presence of `tsconfig.json`)
* The `types/` directory should be added to `.gitignore` — regenerate it from migrations instead
* Do not edit generated files — they will be overwritten on the next `migrate` or `types` run
* For custom cast classes, the column falls back to `any` — add a manual override if needed
