Suprnova's Inertia bridge has one rule: the props a handler sends and the props a component receives are the same type, and a machine checks it.
On the Rust side, a page's props are a struct:
inertia_response!("docs/Index", DocsPageProps { .. }) refuses to compile
if frontend/src/pages/docs/Index.vue doesn't exist - dead page references
are a build error, not a 3 a.m. discovery.
Then suprnova generate-types walks every InertiaProps struct and emits
TypeScript interfaces:
export interface DocsPageProps {
groups: Array<DocsGroup>;
chapter: DocsChapterProps;
}
Rename a Rust field and the TypeScript compiler points at every component
that needs updating. suprnova serve runs the generator as a watcher, so
the loop is: edit the struct, save, watch vue-tsc light up.
Nested types ride along
The generator resolves nested DTOs transitively - any struct your project
defines gets a precise named interface when a prop reaches it, whether or
not it derives InertiaProps or Data. A plain struct DocsGroup two
levels down still comes out as Array<DocsGroup>, not unknown. Only
types the generator genuinely can't see into - external crate types,
enums, tuple structs - degrade to unknown, and each one warns loudly:
⚠ Prop type `serde_json::Value` (referenced by `AdminProps.payload`)
isn't a struct this project defines - emitting `unknown`.
This site is built with Suprnova, and the whole surface - docs, blog, community, resources, admin - runs on exactly this pipeline. The generated file is committed, so a type drift shows up in review as a diff, not as a runtime surprise.
Read more in the Frontend chapter of the manual.


Comments 0