Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type deprecations for types now in React Router #5679

Merged
merged 8 commits into from
Mar 21, 2023
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/flat-boxes-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@remix-run/react": patch
"@remix-run/server-runtime": patch
---

Add type deprecations for types now in React Router
17 changes: 4 additions & 13 deletions packages/remix-react/components.tsx
Original file line number Diff line number Diff line change
@@ -108,19 +108,6 @@ function useRemixContext(): RemixContextObject {
return context;
}

////////////////////////////////////////////////////////////////////////////////
// RemixEntry

export function RemixEntry(props: {
context: EntryContext;
action: NavigationType;
location: Location;
navigator: Navigator;
static?: boolean;
}) {
return <h1>Not Implemented!</h1>;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer used

////////////////////////////////////////////////////////////////////////////////
// RemixRoute

@@ -743,6 +730,8 @@ export function Meta() {
return future?.v2_meta ? <V2Meta /> : <V1Meta />;
}

// TODO: The RR version is just missing the generic and resolve is
// `TrackedPromise | any`. Should we add the generic in RR?
export interface AwaitProps<Resolve> {
children: React.ReactNode | ((value: Awaited<Resolve>) => React.ReactNode);
errorElement?: React.ReactNode;
@@ -1103,6 +1092,8 @@ function dedupe(array: any[]) {
}

// TODO: Can this be re-exported from RR?
// Yes, but data -> unknown and handle -> unknown. Is handle forced to
// be an object in remix?
export interface RouteMatch {
/**
* The id of the matched route
7 changes: 0 additions & 7 deletions packages/remix-react/data.ts
Original file line number Diff line number Diff line change
@@ -2,16 +2,9 @@ import {
AbortedDeferredError,
UNSAFE_DeferredData as DeferredData,
} from "@remix-run/router";
import type { FormMethod as FormMethodRR } from "react-router-dom";

export type AppData = any;

export type FormMethod = FormMethodRR;

export type FormEncType =
| "application/x-www-form-urlencoded"
| "multipart/form-data";

MichaelDeBoey marked this conversation as resolved.
Show resolved Hide resolved
export function isCatchResponse(response: any): boolean {
return (
response instanceof Response &&
4 changes: 4 additions & 0 deletions packages/remix-react/errors.ts
Original file line number Diff line number Diff line change
@@ -3,6 +3,10 @@ import { ErrorResponse } from "@remix-run/router";

import type { AppData } from "./data";

/**
* @deprecated in favor of React Router `ErrorResponse`
* TODO: Need to add generics in RR
*/
export interface ThrownResponse<
Status extends number = number,
Data = AppData
4 changes: 2 additions & 2 deletions packages/remix-react/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export type { RemixBrowserProps } from "./browser";
export { RemixBrowser } from "./browser";
export type {
FormEncType,
FormMethod,
FormProps,
Location,
NavigateFunction,
@@ -63,8 +65,6 @@ export {
RemixContext as UNSAFE_RemixContext,
} from "./components";

export type { FormMethod, FormEncType } from "./data";

export type { ThrownResponse } from "./errors";
export { useCatch } from "./errorBoundaries";

5 changes: 0 additions & 5 deletions packages/remix-react/routeData.ts

This file was deleted.

4 changes: 3 additions & 1 deletion packages/remix-react/routeModules.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ComponentType } from "react";
import type { RouterState } from "@remix-run/router";
import type {
DataRouteMatch,
Params,
@@ -9,7 +10,8 @@ import type {
import type { AppData } from "./data";
import type { LinkDescriptor } from "./links";
import type { EntryRoute } from "./routes";
import type { RouteData } from "./routeData";

type RouteData = RouterState["loaderData"];
MichaelDeBoey marked this conversation as resolved.
Show resolved Hide resolved

export interface RouteModules {
[routeId: string]: RouteModule;
55 changes: 1 addition & 54 deletions packages/remix-react/transition.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import type { Location, NavigationType as Action } from "react-router-dom";

export interface CatchData<T = any> {
status: number;
statusText: string;
data: T;
}
import type { Location } from "react-router-dom";

export interface Submission {
action: string;
@@ -81,29 +75,6 @@ export type TransitionStates = {

export type Transition = TransitionStates[keyof TransitionStates];

export type Redirects = {
Loader: {
isRedirect: true;
type: "loader";
setCookie: boolean;
};
Action: {
isRedirect: true;
type: "action";
setCookie: boolean;
};
LoaderSubmission: {
isRedirect: true;
type: "loaderSubmission";
setCookie: boolean;
};
FetchAction: {
isRedirect: true;
type: "fetchAction";
setCookie: boolean;
};
};

MichaelDeBoey marked this conversation as resolved.
Show resolved Hide resolved
// TODO: keep data around on resubmission?
export type FetcherStates<TData = any> = {
Idle: {
@@ -181,30 +152,6 @@ export type FetcherStates<TData = any> = {
export type Fetcher<TData = any> =
FetcherStates<TData>[keyof FetcherStates<TData>];

export class CatchValue {
constructor(
public status: number,
public statusText: string,
public data: any
) {}
}

export type NavigationEvent = {
type: "navigation";
action: Action;
location: Location;
submission?: Submission;
};

export type FetcherEvent = {
type: "fetcher";
key: string;
submission?: Submission;
href: string;
};

export type DataEvent = NavigationEvent | FetcherEvent;

export const IDLE_TRANSITION: TransitionStates["Idle"] = {
state: "idle",
submission: undefined,
2 changes: 2 additions & 0 deletions packages/remix-server-runtime/data.ts
Original file line number Diff line number Diff line change
@@ -21,6 +21,8 @@ export interface AppLoadContext {

/**
* Data for a route that was returned from a `loader()`.
*
* @deprecated
*/
export type AppData = any;

5 changes: 4 additions & 1 deletion packages/remix-server-runtime/errors.ts
Original file line number Diff line number Diff line change
@@ -43,7 +43,10 @@ import { isRouteErrorResponse } from "@remix-run/router";
* line.
*/

// TODO Re-export as ErrorResponse?
/**
* @deprecated in favor of the `ErrorResponse` class in React Router.
* TODO: Need to add generics in RR
*/
export interface ThrownResponse<T = any> {
status: number;
statusText: string;
42 changes: 14 additions & 28 deletions packages/remix-server-runtime/responses.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
defer as routerDefer,
json as routerJson,
redirect as routerRedirect,
type UNSAFE_DeferredData as DeferredData,
type TrackedPromise,
} from "@remix-run/router";
@@ -13,11 +15,15 @@ export type TypedDeferredData<Data extends Record<string, unknown>> = Pick<
data: Data;
};

// TODO: The RR version of this is the same minus the generic. Should we add
// that over there and remove this?
export type DeferFunction = <Data extends Record<string, unknown>>(
data: Data,
init?: number | ResponseInit
) => TypedDeferredData<Data>;

// TODO: The RR version of this is identical except it's generic doesn't
// `extends unknown`. Should we add that over there and remove this?
export type JsonFunction = <Data extends unknown>(
brophdawg11 marked this conversation as resolved.
Show resolved Hide resolved
data: Data,
init?: number | ResponseInit
@@ -39,28 +45,18 @@ export type TypedResponse<T extends unknown = unknown> = Omit<
* @see https://remix.run/utils/json
*/
export const json: JsonFunction = (data, init = {}) => {
let responseInit = typeof init === "number" ? { status: init } : init;

let headers = new Headers(responseInit.headers);
if (!headers.has("Content-Type")) {
headers.set("Content-Type", "application/json; charset=utf-8");
}

return new Response(JSON.stringify(data), {
...responseInit,
headers,
});
return routerJson(data, init);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use router methods directly, but preserve typecasting on the returned values

};

/**
* This is a shortcut for creating `application/json` responses. Converts `data`
* to JSON and sets the `Content-Type` header.
* This is a shortcut for creating Remix deferred responses
*
* @see https://remix.run/api/remix#json
* @see https://remix.run/docs/utils/defer
*/
export const defer: DeferFunction = (data, init = {}) => {
let responseInit = typeof init === "number" ? { status: init } : init;

// TODO: Do we need this or is this copy/paste from json()?
brophdawg11 marked this conversation as resolved.
Show resolved Hide resolved
let headers = new Headers(responseInit.headers);
if (!headers.has("Content-Type")) {
headers.set("Content-Type", "application/json; charset=utf-8");
@@ -72,6 +68,8 @@ export const defer: DeferFunction = (data, init = {}) => {
}) as TypedDeferredData<typeof data>;
};

// TODO: The RR version is identical minus `TypedResponse` and it just returns
// a `Response`. Should we add that over there?
export type RedirectFunction = (
url: string,
init?: number | ResponseInit
@@ -84,20 +82,7 @@ export type RedirectFunction = (
* @see https://remix.run/utils/redirect
*/
export const redirect: RedirectFunction = (url, init = 302) => {
let responseInit = init;
if (typeof responseInit === "number") {
responseInit = { status: responseInit };
} else if (typeof responseInit.status === "undefined") {
responseInit.status = 302;
}

let headers = new Headers(responseInit.headers);
headers.set("Location", url);

return new Response(null, {
...responseInit,
headers,
}) as TypedResponse<never>;
return routerRedirect(url, init) as TypedResponse<never>;
};

export function isDeferredData(value: any): value is DeferredData {
@@ -122,6 +107,7 @@ export function isResponse(value: any): value is Response {
);
}

//TODO(v2): Can we leverage this stuff from RR?
const redirectStatusCodes = new Set([301, 302, 303, 307, 308]);
export function isRedirectStatusCode(statusCode: number): boolean {
return redirectStatusCodes.has(statusCode);
5 changes: 0 additions & 5 deletions packages/remix-server-runtime/routeData.ts

This file was deleted.

20 changes: 18 additions & 2 deletions packages/remix-server-runtime/routeModules.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,44 @@
import type { Location, Params } from "@remix-run/router";
import type { Location, Params, RouterState } from "@remix-run/router";
import type { ComponentType } from "react";

import type { AppLoadContext, AppData } from "./data";
import type { LinkDescriptor } from "./links";
import type { RouteData } from "./routeData";
import type { Route } from "./routes";
import type { SerializeFrom } from "./serialize";

type RouteData = RouterState["loaderData"];

export interface RouteModules<RouteModule> {
[routeId: string]: RouteModule;
}

/**
* The arguments passed to ActionFunction and LoaderFunction.
*
* @deprecated in favor of React Router `LoaderFunctionArgs` and `ActionFunctionArgs`
* TODO: In RR context is optional and typed as `any` - can we drop this in v2
* in favor of that?
*/
export interface DataFunctionArgs {
request: Request;
context: AppLoadContext;
params: Params;
}

/**
* @deprecated in favor of React Router `LoaderFunctionArgs`
*/
export type LoaderArgs = DataFunctionArgs;

/**
* @deprecated in favor of React Router `ActionFunctionArgs`
*/
export type ActionArgs = DataFunctionArgs;

/**
* A function that handles data mutations for a route.
*
* @deprecated in favor of React Router `ActionFunction`
*/
export interface ActionFunction {
(args: DataFunctionArgs):
@@ -66,6 +80,8 @@ export interface LinksFunction {

/**
* A function that loads data for a route.
*
* @deprecated in favor of React Router `LoaderFunction`
brophdawg11 marked this conversation as resolved.
Show resolved Hide resolved
*/
export interface LoaderFunction {
(args: DataFunctionArgs):