TypeScript β Python type generation.
The Type Sync Pipeline ensures end-to-end type safety between TypeScript and Python codebases, eliminating type drift.
1
2
3
4
5
6
7
8
9
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β Supabase β β β TypeScript β β β Python β
β (Schema) β β Types β β Pydantic β
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β β β
βββββββββββββββββββββ΄ββββββββββββββββββββ
β
Type Validator
(Consistency Check)
1
2
3
4
5
6
7
8
9
# Full type generation pipeline
just gen-types # Runs gen-types-ts then gen-types-py
# Individual steps
just gen-types-ts # Supabase β TypeScript
just gen-types-py # TypeScript β Python Pydantic
# Validation
just check-types # Verify consistency, fail if drift detected
1
2
3
4
# From Supabase schema
just gen-types-ts
# Output: libs/shared/types/src/database.types.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Generated TypeScript types
export interface Database {
public: {
Tables: {
cases: {
Row: {
id: string;
title: string;
status: 'open' | 'closed' | 'pending';
created_at: string;
};
Insert: Omit<Row, 'id' | 'created_at'>;
Update: Partial<Row>;
};
};
};
}
1
2
3
4
# From TypeScript types
just gen-types-py
# Output: libs/shared/types-py/src/models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Generated Pydantic models
from pydantic import BaseModel
from typing import Literal
from datetime import datetime
class CaseRow(BaseModel):
id: str
title: str
status: Literal['open', 'closed', 'pending']
created_at: datetime
class CaseInsert(BaseModel):
title: str
status: Literal['open', 'closed', 'pending']
class CaseUpdate(BaseModel):
title: str | None = None
status: Literal['open', 'closed', 'pending'] | None = None
| TypeScript | Python |
|---|---|
string |
str |
number |
int \| float |
boolean |
bool |
Date |
datetime |
null |
None |
T[] |
list[T] |
Record<K, V> |
dict[K, V] |
A \| B |
A \| B (Union) |
'a' \| 'b' |
Literal['a', 'b'] |
1
just check-types
This verifies that:
Policy "BidirectionalConsistency" per Constraint Obligation priority 10 as:
hash(generate_ts(schema)) = hash(reverse_transpile(generate_py(ts)))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# .github/workflows/type-check.yml
jobs:
type-safety:
steps:
- name: Generate Types
run: just gen-types
- name: Check Consistency
run: just check-types
- name: Fail on Drift
run: |
git diff --exit-code libs/shared/types/
git diff --exit-code libs/shared/types-py/
| Issue | Solution |
|---|---|
| Types out of sync | Run just gen-types |
| Supabase schema changed | Regenerate from source |
| Unknown type mapping | Add custom mapper in gen_py_types.py |