Skip to content

Commit

Permalink
defineRoute$ types
Browse files Browse the repository at this point in the history
  • Loading branch information
pcattori committed May 28, 2024
1 parent ce52393 commit 9c66afa
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 6 deletions.
77 changes: 77 additions & 0 deletions packages/react-router/lib/router/define-route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import type { ReactNode } from "react";

interface Context {} // TODO: AppLoadContext?

type MaybePromise<T> = T | Promise<T>;

type Serializable =
| undefined
| null
| boolean
| string
| symbol
| number
| Array<Serializable>
| { [key: PropertyKey]: Serializable }
| bigint
| Date
| URL
| RegExp
| Error
| Map<Serializable, Serializable>
| Set<Serializable>
| Promise<Serializable>;

export type TypedResponse<T = unknown> = Omit<Response, "json"> & {
json(): Promise<T>;
};

type DataFunctionReturnValue =
| Serializable
// TODO: | TypedDeferredData<Record<string, unknown>> // do we want to allow `defer()` for back compat?
| TypedResponse<Record<string, unknown>>;

// TODO: clientLoader and all the other route module export APIs (meta, handle, ErrorBoundary, etc.)

export type ResponseStub = {
status: number | undefined;
headers: Headers;
};

// loader
type LoaderArgs<Param extends string> = {
context: Context;
request: Request;
params: Record<Param, string>;
response: ResponseStub;
};
export type Loader<Param extends string> = (
args: LoaderArgs<Param>
) => MaybePromise<DataFunctionReturnValue>;

// action
type ActionArgs<Param extends string> = {
context: Context;
request: Request;
params: Record<Param, string>;
response: ResponseStub;
};
export type Action<Param extends string> = (
args: ActionArgs<Param>
) => MaybePromise<DataFunctionReturnValue>;

type Component<P extends string, L extends Loader<P>> = (args: {
params: string extends P ? Record<never, string> : Record<P, string>;
data: Awaited<ReturnType<L>>;
}) => ReactNode;

export const defineRoute$ = <
const P extends string,
L extends Loader<P>,
A extends Action<P>
>(route: {
params?: P[];
loader?: L;
action?: A;
component?: Component<NoInfer<P>, NoInfer<L>>;
}) => route;
64 changes: 64 additions & 0 deletions packages/react-router/lib/router/routes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
```ts
export default createRoute$({
params: ["id"], // we want to know params at _build_ time!
search: ["brand"],
loader:,
component:,
})
```

```ts
// routes.ts
export default flatRoutes()

export default remixRoutesDsl({
index: ,
layout: ,
"/about": ""
})

let routes = [
{
layout: "./auth.tsx",
children: [
{
path: "login",
file: "./auth/login.tsx",
},
{
path: "logout",
file: "./auth/logout.tsx",
},
{
path: "signup",
file: "./auth/signup.tsx",
},
],
},
];
export default routes

```

defineRoutes([
layout("./auth.tsx", [
route("login", "./auth/login.tsx"),
route("logout", "./auth/logout.tsx"),
route("signup", "./auth/signup.tsx"),
]),
layout("./app.tsx", [
route("home", "./app/dashboard.tsx"),
route("settings", "./app/settings.tsx"),
route("projects/:id", "./app/project.tsx"),
layout("./app/calendar.tsx", [
route(":year/:month", "./app/calendar.tsx"),
route("today", "./app/calendar.tsx"),
route("new-calendar", "./app/new-calendar.tsx"),
]),
]),
layout("./public-layout.tsx", [
index("./landing.tsx"),
route("about", "./pages/about.tsx"),
route("contact", "./pages/about.tsx"),
]),
});
10 changes: 4 additions & 6 deletions packages/react-router/lib/router/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ export type Submission =
* Arguments passed to route loader/action functions. Same for now but we keep
* this as a private implementation detail in case they diverge in the future.
*/
interface DataFunctionArgs<Context> {
type DataFunctionArgs<Context> = {
request: Request;
params: Params;
context?: Context;
}
};

// TODO: (v7) Change the defaults from any to unknown in and remove Remix wrappers:
// ActionFunction, ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs
Expand All @@ -158,14 +158,12 @@ interface DataFunctionArgs<Context> {
/**
* Arguments passed to loader functions
*/
export interface LoaderFunctionArgs<Context = any>
extends DataFunctionArgs<Context> {}
export type LoaderFunctionArgs<Context = any> = DataFunctionArgs<Context>;

/**
* Arguments passed to action functions
*/
export interface ActionFunctionArgs<Context = any>
extends DataFunctionArgs<Context> {}
export type ActionFunctionArgs<Context = any> = DataFunctionArgs<Context>;

/**
* Loaders and actions can return anything except `undefined` (`null` is a
Expand Down

0 comments on commit 9c66afa

Please sign in to comment.