Skip to content

feat: Add rake task to generate TypeScript types - #219

Draft
tvdeyen wants to merge 2 commits into
mainfrom
create-typescript-types-rake-task
Draft

tvdeyen wants to merge 2 commits into
mainfrom
create-typescript-types-rake-task

Conversation

@tvdeyen

@tvdeyen tvdeyen commented Sep 29, 2026

Copy link
Copy Markdown
Member

Frontend apps consuming the API have no types for the elements and page layouts a host app defines, so a typo in an ingredient role or a page layout name only shows up at runtime. bin/rails alchemy:json_api:generate_types generates a .d.ts file from the app's elements.yml and page_layouts.yml that describes the output of deserialize, so frontends can write deserialize<AlchemyPage>(json) and narrow on page.page_layout and element.name, with ingredients narrowed by role, select values as literal unions and nested elements restricted to nestable_elements.

The attribute types are declared next to the attributes in each serializer via typelize, because neither the database schema nor Alchemy's models know them: ingredient fields live in the untyped data JSON column and many attributes are computed in the serializers. A spec fails whenever a serializer attribute has no declared type (or a declaration outlives its attribute), so the types cannot silently drift from the API. Relationship types are derived from the serializers, including lazy_load_data, which the deserializer turns into null unless the relationship was included.

Typelizer was considered, but it has no jsonapi-serializer adapter and generates one type per serializer, so it cannot produce the per-definition types that are the point of this feature. typelize uses the same attribute: "type" shape, which keeps a later switch mechanical.

The dummy app's news element carried rss_title/rss_description, which Alchemy's IngredientDefinition rejects, so they are removed in a separate commit.

Alchemy's IngredientDefinition raises an UnknownAttributeError for rss_title and rss_description, so reading the ingredient definitions of the dummy app's news element fails.
Frontend apps consuming the API have no types for the elements and page layouts a host app defines, so they cannot narrow pages by page layout or elements by name. The alchemy:json_api:generate_types task generates them from the element and page layout definitions, with the attribute types declared next to the attributes in each serializer via typelize, so the serializers stay the single source of the API's shape.
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