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 stringtarget: 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
Noneif 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 fileoutput_path: Path to output file (optional, derives from input if not provided)target: Target format (same ascompilemethod)
Returns:
Trueif successful,Falseotherwise
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
- @dataset.sh/typelang - TypeScript/JavaScript implementation of Typelang
- typelang-spec - Language specification
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a4b42bf799f4384a329f48f0bce0c5d50b04ba7df1908736abe36b0c1883313
|
|
| MD5 |
097b47ec1ce79847de0aca08f67ab823
|
|
| BLAKE2b-256 |
7c3da4ec0ee6f4377a48a5bb2a12cb7893256ba0669273f2e32cb5c465365459
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74c7e482a1324bcf440ba0ff3fa30b501d68103c9b3d9113e5742f926f87484f
|
|
| MD5 |
420cdd8773dacd6158217e7258bf7cd9
|
|
| BLAKE2b-256 |
1d2ef9148c50df5dedbc2574051f770df4fa882dfd2c8a83d1dfb82224974e11
|