# 📦 Root Models and Type Aliases

When a schema defines a simple type (not an object with properties), `datamodel-code-generator` creates a root model. If you don't want to introduce a new level of attribute access (`.root`) or want to use generated types as plain Python types in non-Pydantic code, you can use the `--use-type-alias` flag to generate type aliases instead of root models.

## ⚠️ Notes and Limitations

**This functionality is experimental!** Here are a few known issues:

- 📌 RootModel and type aliases do not fully support field-specific metadata (default, alias, etc). See [Named Type Aliases](https://docs.pydantic.dev/latest/concepts/types/#named-type-aliases) for details.
- 🚫 Type aliases do not support some RootModel features (e.g. `model_config`)
- 📄 A RootModel or type alias is also generated for the main schema, allowing you to define a single type alias from a schema file (e.g. `model.json` containing `{"title": "MyString", "type": "string"}`)
## 📊 Type Alias Behavior by Output Type and Python Version

The type of type alias generated depends on the output model type and target Python version:

| Output Type | Python 3.12+ | Python 3.10-3.11 |
|-------------|--------------|------------------|
| **Pydantic v2** | `type` statement | `TypeAliasType` (typing_extensions) |
| **TypedDict** | `type` statement | `TypeAlias` |
| **dataclasses** | `type` statement | `TypeAlias` |
| **msgspec** | `type` statement | `TypeAlias` |

### 🤔 Why the difference?

- **Pydantic v2** requires `TypeAliasType` because it cannot properly handle `TypeAlias` annotations
- **Other output types** (TypedDict, dataclasses, msgspec) use `TypeAlias` for better compatibility with libraries that may not expect `TypeAliasType` objects
- **Python 3.12+** uses the native `type` statement for all output types

## 📝 Example

### model.json

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "UserId": {
      "type": "string"
    },
    "Status": {
      "anyOf": [
        {"type": "string"},
        {"type": "integer"}
      ]
    },
    "User": {
      "type": "object",
      "properties": {
        "id": {"$ref": "#/definitions/UserId"},
        "status": {"$ref": "#/definitions/Status"}
      }
    }
  }
}
```

### 🔸 Pydantic v2

#### Generating RootModel

```bash
datamodel-codegen --input model.json --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel --output model.py
```

### ✨ Generated model.py (Pydantic v2)

```python
# generated by datamodel-codegen:
#   filename:  model.json

from __future__ import annotations

from typing import Any, Optional, Union

from pydantic import BaseModel, RootModel


class Model(RootModel[Any]):
    root: Any


class UserId(RootModel[str]):
    root: str


class Status(RootModel[Union[str, int]]):
    root: Union[str, int]


class User(BaseModel):
    id: Optional[UserId] = None
    status: Optional[Status] = None
```

#### Generating type statement (Python 3.12+)

```bash
datamodel-codegen --input model.json --input-file-type jsonschema --output-model-type pydantic_v2.BaseModel --use-type-alias --target-python-version 3.12 --output model.py
```

### ✨ Generated model.py (Python 3.12+ type statement)

```python
# generated by datamodel-codegen:
#   filename:  model.json

from __future__ import annotations

from typing import Any, Optional, Union

from pydantic import BaseModel

type Model = Any


type UserId = str


type Status = Union[str, int]


class User(BaseModel):
    id: Optional[UserId] = None
    status: Optional[Status] = None
```

---

## 📖 See Also

- 🖥️ [CLI Reference: `--use-type-alias`](cli-reference/typing-customization.md#use-type-alias) - Detailed CLI option documentation
- 🎯 [CLI Reference: `--target-python-version`](cli-reference/model-customization.md#target-python-version) - Control Python version-specific syntax
