Skip to main content

TypeScript-flavored schema definition language for cross-platform type generation

Project description

Typelang Python

Python implementation of Typelang - A TypeScript-flavored schema definition language for cross-platform type generation.

Features

  • TypeScript-like syntax - Familiar and easy to learn
  • Multiple targets - Generate TypeScript, Python (dataclass/Pydantic), and JSON Schema
  • CLI and API - Use as a command-line tool or programmatic library
  • Rich metadata - Support for JSDoc comments and custom attributes
  • Generic types - Support for generic type parameters
  • Pure Python - No external dependencies for core functionality

Installation

Using pip

pip install typelang

Using uv (recommended)

uv add typelang

From source

git clone https://github.com/dataset-sh/typelang-py
cd typelang-py
uv sync

Quick Start

CLI Usage

# Generate TypeScript types
typelang schema.tl -o types.ts

# Generate Python Pydantic models
typelang schema.tl -t py-pydantic -o models.py

# Generate Python dataclasses
typelang schema.tl -t py-dataclass -o models.py

# Generate JSON Schema
typelang schema.tl -t jsonschema -o schema.json

# Output to stdout
typelang schema.tl -t ts

# View intermediate representation
typelang schema.tl -t ir

Programmatic API

from typelang import Compiler

source = """
type User = {
  id: string
  name: string
  email?: string
  age: int
}
"""

compiler = Compiler()

# Generate TypeScript
typescript = compiler.compile(source, target="typescript")
print(typescript)

# Generate Python Pydantic
pydantic = compiler.compile(source, target="python-pydantic")
print(pydantic)

# Generate JSON Schema
jsonschema = compiler.compile(source, target="jsonschema")
print(jsonschema)

Schema Language

Basic Types

type User = {
  // Primitive types
  id: string
  age: int
  score: float
  active: bool
  
  // Optional fields
  email?: string
  phone?: string
  
  // Arrays
  tags: string[]
  scores: float[]
  
  // Maps/Dictionaries
  metadata: Dict<string, any>
  settings: Dict<string, bool>
}

Generic Types

// Generic type parameters
type Container<T> = {
  value: T
  timestamp: string
}

type Result<T, E> = {
  success: bool
  data?: T
  error?: E
}

// Using generic types
type UserContainer = Container<User>

Union Types

// String literal unions (enums)
type Status = "draft" | "published" | "archived"

// Mixed unions
type StringOrNumber = string | int

// Complex unions
type Response = 
  | { success: true, data: User }
  | { success: false, error: string }

Nested Objects

type Address = {
  street: string
  city: string
  country: string
}

type User = {
  name: string
  address: Address  // Nested type reference
  
  // Inline nested object
  contact: {
    email: string
    phone?: string
  }
}

Metadata and Attributes

/** User model for the application */
@table("users")
@index(["email", "username"])
type User = {
  /** Unique identifier */
  @primary
  @generated("uuid")
  id: string
  
  /** User's email address */
  @unique
  @validate("email")
  email: string
  
  /** User's display name */
  @minLength(3)
  @maxLength(50)
  name: string
}

CLI Options

Usage: typelang [-h] [-o OUTPUT] [-t TARGET] input

Typelang compiler - compile schema definitions to various target languages

positional arguments:
  input                Input Typelang file (.tl or .md)

options:
  -h, --help           show this help message and exit
  -o, --output OUTPUT  Output file path (optional, defaults to stdout)
  -t, --target TARGET  Target format (default: ts). Available: ts, py-dataclass, py-pydantic, jsonschema, ir

Examples:
  typelang schema.tl -o types.ts
  typelang schema.tl -t py-pydantic -o models.py
  typelang schema.tl -t jsonschema
  typelang schema.tl -t ir -o schema.ir.json

API Reference

Compiler class

The main compiler class for transforming Typelang source to various targets.

from typelang import Compiler

compiler = Compiler()

compile(source: str, target: str = "typescript") -> Optional[str]

Compiles Typelang source code to the specified target format.

Parameters:

  • source: Typelang source code string
  • target: Target format - one of:
    • "typescript" or "ts" - TypeScript type definitions
    • "python-dataclass" or "py-dataclass" - Python dataclasses
    • "python-pydantic" or "py-pydantic" - Python Pydantic models
    • "jsonschema" - JSON Schema
    • "ir" - Intermediate Representation (JSON)

Returns:

  • Generated code as string, or None if compilation failed

Example:

from typelang import Compiler

schema = """
/** Product in our catalog */
@table("products")
type Product = {
  /** Unique product ID */
  @primary
  id: string
  
  /** Product display name */
  name: string
  
  /** Price in cents */
  price: int
  
  /** Available stock */
  stock: int
  
  /** Product categories */
  categories: string[]
  
  /** Product status */
  status: "draft" | "published" | "out-of-stock"
}

/** Customer order */
type Order = {
  id: string
  customerId: string
  products: Product[]
  total: float
  status: "pending" | "paid" | "shipped" | "delivered"
  createdAt: string
}
"""

compiler = Compiler()

# Generate TypeScript
typescript = compiler.compile(schema, target="typescript")
if typescript:
    with open("types.ts", "w") as f:
        f.write(typescript)

# Generate Python Pydantic
pydantic = compiler.compile(schema, target="python-pydantic")
if pydantic:
    with open("models.py", "w") as f:
        f.write(pydantic)

# Generate JSON Schema
jsonschema = compiler.compile(schema, target="jsonschema")
if jsonschema:
    with open("schema.json", "w") as f:
        f.write(jsonschema)

# Check for errors
if compiler.get_errors():
    print("Compilation errors:")
    for error in compiler.get_errors():
        print(f"  - {error}")

get_errors() -> List[str]

Returns a list of compilation errors encountered during the last compilation.

compile_file(input_path: str, output_path: Optional[str] = None, target: str = "typescript") -> bool

Convenience function to compile a file directly.

Parameters:

  • input_path: Path to input Typelang file
  • output_path: Path to output file (optional, derives from input if not provided)
  • target: Target format (same as compile method)

Returns:

  • True if successful, False otherwise

Example:

from typelang import compile_file

# Compile with automatic output path
success = compile_file("schema.tl", target="python-pydantic")
# Creates schema_pydantic.py

# Compile with specific output path
success = compile_file("schema.tl", "models.py", target="python-pydantic")

Built-in Types

Typelang TypeScript Python JSON Schema
string string str "type": "string"
int number int "type": "integer"
float number float "type": "number"
bool boolean bool "type": "boolean"
any any Any {}
T[] T[] List[T] "type": "array"
Dict<K,V> Record<K,V> Dict[K,V] "type": "object"
T? T | undefined Optional[T] not required

Output Examples

TypeScript Output

export type User = {
  id: string
  name: string
  email?: string
  age: number
}

Python Pydantic Output

from pydantic import BaseModel, Field
from typing import Optional

class User(BaseModel):
    id: str
    name: str
    email: Optional[str] = Field(default=None)
    age: int

Python Dataclass Output

from dataclasses import dataclass
from typing import Optional

@dataclass
class User:
    id: str
    name: str
    age: int
    email: Optional[str] = None

JSON Schema Output

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "id": {"type": "string"},
    "name": {"type": "string"},
    "email": {"type": "string"},
    "age": {"type": "integer"}
  },
  "required": ["id", "name", "age"]
}

Development

Setup

# Clone the repository
git clone https://github.com/dataset-sh/typelang-py
cd typelang-py

# Install with uv
uv sync

# Or install with pip
pip install -e .

Running Tests

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov

# Run specific test file
uv run pytest tests/test_compiler.py

Project Structure

typelang-py/
\x00\x00 src/
   \x00\x00 typelang_py/
       \x00\x00 __init__.py          # Package exports
       \x00\x00 __main__.py          # CLI entry point
       \x00\x00 ast_types.py         # AST type definitions
       \x00\x00 ir_types.py          # IR type definitions
       \x00\x00 lexer.py             # Tokenizer
       \x00\x00 parser.py            # Parser
       \x00\x00 transformer.py       # AST to IR transformer
       \x00\x00 compiler.py          # Main compiler
       \x00\x00 codegen_typescript.py    # TypeScript generator
       \x00\x00 codegen_python_dataclass.py  # Dataclass generator
       \x00\x00 codegen_python_pydantic.py   # Pydantic generator
       \x00\x00 codegen_jsonschema.py        # JSON Schema generator
\x00\x00 tests/
   \x00\x00 test_compiler.py        # Compiler tests
   \x00\x00 test_cli_e2e.py        # End-to-end CLI tests
\x00\x00 pyproject.toml              # Project configuration
\x00\x00 README.md                   # This file

License

MIT � Hao Wu

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Related Projects

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

typelang-0.0.1.tar.gz (50.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

typelang-0.0.1-py3-none-any.whl (27.2 kB view details)

Uploaded Python 3

File details

Details for the file typelang-0.0.1.tar.gz.

File metadata

  • Download URL: typelang-0.0.1.tar.gz
  • Upload date:
  • Size: 50.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.2

File hashes

Hashes for typelang-0.0.1.tar.gz
Algorithm Hash digest
SHA256 1a4b42bf799f4384a329f48f0bce0c5d50b04ba7df1908736abe36b0c1883313
MD5 097b47ec1ce79847de0aca08f67ab823
BLAKE2b-256 7c3da4ec0ee6f4377a48a5bb2a12cb7893256ba0669273f2e32cb5c465365459

See more details on using hashes here.

File details

Details for the file typelang-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: typelang-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 27.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.2

File hashes

Hashes for typelang-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 74c7e482a1324bcf440ba0ff3fa30b501d68103c9b3d9113e5742f926f87484f
MD5 420cdd8773dacd6158217e7258bf7cd9
BLAKE2b-256 1d2ef9148c50df5dedbc2574051f770df4fa882dfd2c8a83d1dfb82224974e11

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page