Skip to content

definePage curried API with type inference #9

@qantrepreneur

Description

@qantrepreneur

What to build

Implement the definePage function — the primary API for declaring page routes. Uses a curried pattern for full TypeScript inference:

export default definePage("/blog/[slug]")({
  template: "marketing",
  loader: async ({ request, ctx }) => {
    return { post: await getPost(ctx.params.slug) };
  },
  defineSlots: ({ loaderData }) => ({
    main: <BlogPost post={loaderData.post} />,
  }),
  meta: ({ loaderData }) => ({
    title: loaderData.post.title,
  }),
});

The first call accepts the route path string and returns a function. The second call accepts the page config. This pattern allows TypeScript to:

  1. Infer params from the route path (via RouteMap)
  2. Infer loaderData type from the loader return
  3. Validate template against TemplateRegistry

At runtime, definePage is an identity function — it returns the config unchanged.

Acceptance criteria

  • Curried definePage("/path")({...}) signature
  • template field constrained to keyof TemplateRegistry
  • loader receives { request: Request, ctx: Context } with typed params
  • defineSlots receives { loaderData } typed from loader return
  • meta accepts static object or function of { loaderData }
  • loader is optional (defineSlots receives { loaderData: undefined } when omitted)
  • Runtime behavior is identity (returns input unchanged)
  • Type tests verifying inference chain works end-to-end

Blocked by

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions