From d533ed8cb2863c4f4337a9e177fbfde71e770dac Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Tue, 28 May 2024 12:06:12 -0400 Subject: [PATCH] defineRoute$ types --- .../react-router/lib/router/define-route.ts | 77 +++++++++++++++++++ packages/react-router/lib/router/utils.ts | 10 +-- 2 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 packages/react-router/lib/router/define-route.ts diff --git a/packages/react-router/lib/router/define-route.ts b/packages/react-router/lib/router/define-route.ts new file mode 100644 index 0000000000..d3e99e669c --- /dev/null +++ b/packages/react-router/lib/router/define-route.ts @@ -0,0 +1,77 @@ +import type { ReactNode } from "react"; + +interface Context {} // TODO: AppLoadContext? + +type MaybePromise = T | Promise; + +type Serializable = + | undefined + | null + | boolean + | string + | symbol + | number + | Array + | { [key: PropertyKey]: Serializable } + | bigint + | Date + | URL + | RegExp + | Error + | Map + | Set + | Promise; + +export type TypedResponse = Omit & { + json(): Promise; +}; + +type DataFunctionReturnValue = + | Serializable + // TODO: | TypedDeferredData> // do we want to allow `defer()` for back compat? + | TypedResponse>; + +// 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 = { + context: Context; + request: Request; + params: Record; + response: ResponseStub; +}; +export type Loader = ( + args: LoaderArgs +) => MaybePromise; + +// action +type ActionArgs = { + context: Context; + request: Request; + params: Record; + response: ResponseStub; +}; +export type Action = ( + args: ActionArgs +) => MaybePromise; + +type Component

> = (args: { + params: string extends P ? Record : Record; + data: Awaited>; +}) => ReactNode; + +export const defineRoute$ = < + const P extends string, + L extends Loader

, + A extends Action

+>(route: { + params?: P[]; + loader?: L; + action?: A; + component?: Component, NoInfer>; +}) => route; diff --git a/packages/react-router/lib/router/utils.ts b/packages/react-router/lib/router/utils.ts index 561421e777..0af27457d3 100644 --- a/packages/react-router/lib/router/utils.ts +++ b/packages/react-router/lib/router/utils.ts @@ -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 { +type DataFunctionArgs = { request: Request; params: Params; context?: Context; -} +}; // TODO: (v7) Change the defaults from any to unknown in and remove Remix wrappers: // ActionFunction, ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs @@ -158,14 +158,12 @@ interface DataFunctionArgs { /** * Arguments passed to loader functions */ -export interface LoaderFunctionArgs - extends DataFunctionArgs {} +export type LoaderFunctionArgs = DataFunctionArgs; /** * Arguments passed to action functions */ -export interface ActionFunctionArgs - extends DataFunctionArgs {} +export type ActionFunctionArgs = DataFunctionArgs; /** * Loaders and actions can return anything except `undefined` (`null` is a