Skip to content

Replace ts-rs with typeshare for type generation#8

Open
antont wants to merge 1 commit into
mainfrom
feature/typeshare-migration
Open

Replace ts-rs with typeshare for type generation#8
antont wants to merge 1 commit into
mainfrom
feature/typeshare-migration

Conversation

@antont

@antont antont commented Feb 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • Switch from ts-rs to typeshare (by 1Password) for generating TypeScript types from Rust structs
  • Replaces the cargo test export_bindings hack with a clean CLI tool that parses source files directly
  • Consolidates per-type .ts files into a single generated types.ts

What changed

File Change
Cargo.toml ts-rstypeshare dependency
src/models.rs #[derive(TS)] + #[ts(export)]#[typeshare]; counts i64i32
src/handlers.rs Cast query counts as i32 for the new field type
scripts/generate-types.sh cargo testtypeshare CLI
scripts/check-types.sh Updated to diff single file
web/src/types/generated/ 4 per-type files → single types.ts + barrel index.ts
README.md, AGENTS.md Updated docs and gotchas

Notable behavioral differences

  • interface vs type: typeshare generates export interface Foo { ... } instead of export type Foo = { ... } — functionally equivalent for plain data shapes
  • Option<T>: maps to field?: T (optional) instead of field: T | null — the frontend api.ts already converts undefined → null before sending JSON
  • i64 unsupported: typeshare rejects i64 (JSON precision concerns), so counts use i32 which is more than sufficient for todo counts

Test plan

  • cargo build --no-default-features --features sqlite compiles
  • cargo test --no-default-features --features sqlite passes (3/3)
  • typeshare ./src --lang=typescript generates correct output
  • npx tsc --noEmit — TypeScript compiles with new types
  • scripts/generate-types.sh works
  • scripts/check-types.sh passes

🤖 Generated with Claude Code


Note

Medium Risk
Switches the Rust↔TypeScript type generation tool and changes generated type shapes (notably Option<T> now becomes optional fields and counts move to i32), which can surface subtle contract mismatches if regeneration or callers lag behind.

Overview
Replaces the Rust→TypeScript type bridge from ts-rs to typeshare, updating Rust annotations (#[ts(export)]/TS#[typeshare]), build dependencies, and docs.

Updates type generation scripts to run the typeshare CLI and consolidates frontend generated output from per-type files into a single web/src/types/generated/types.ts with a simplified barrel export.

Adjusts API model types for typeshare limitations by changing todo count fields from i64 to i32 and casting query results in list_todos accordingly; the generated TS types now represent Option<T> as optional properties rather than null unions.

Written by Cursor Bugbot for commit ec2e997. This will update automatically on new commits. Configure here.

Switch from ts-rs (derive macro + cargo test export hack) to typeshare
(CLI tool by 1Password) for generating TypeScript interfaces from Rust
structs. This gives us a cleaner generation workflow — typeshare parses
source files directly instead of relying on test side effects.

Key changes:
- `#[derive(TS)] + #[ts(export)]` → `#[typeshare]` attribute
- Per-type .ts files → single generated types.ts
- `cargo test export_bindings` → `typeshare` CLI in scripts
- TodoListResponse counts: i64 → i32 (typeshare doesn't support i64)
- Option<T> now maps to optional fields (T?) instead of T | null

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel

vercel Bot commented Feb 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
todo-rs-ts Ready Ready Preview, Comment Feb 23, 2026 0:19am

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant