Skip to content

Commit

Permalink
do not rely on symbol for filtering out redirects from loader data (
Browse files Browse the repository at this point in the history
  • Loading branch information
pcattori authored Jan 6, 2025
1 parent ebc8241 commit 372e25f
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 15 deletions.
13 changes: 13 additions & 0 deletions .changeset/calm-cycles-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"react-router": patch
---

Do not rely on `symbol` for filtering out `redirect` responses from loader data

Previously, some projects were getting type checking errors like:

```ts
error TS4058: Return type of exported function has or is using name 'redirectSymbol' from external module "node_modules/..." but cannot be named.
```

Now that `symbol`s are not used for the `redirect` response type, these errors should no longer be present.
12 changes: 2 additions & 10 deletions packages/react-router/lib/router/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1367,12 +1367,7 @@ export interface TrackedPromise extends Promise<any> {
export type RedirectFunction = (
url: string,
init?: number | ResponseInit
) => Redirect;

// use a `unique symbol` to create a branded type
// https://egghead.io/blog/using-branded-types-in-typescript
declare const redirectSymbol: unique symbol;
export type Redirect = Response & { [redirectSymbol]: never };
) => Response;

/**
* A redirect response. Sets the status code and the `Location` header.
Expand All @@ -1391,10 +1386,7 @@ export const redirect: RedirectFunction = (url, init = 302) => {
let headers = new Headers(responseInit.headers);
headers.set("Location", url);

return new Response(null, {
...responseInit,
headers,
}) as Redirect;
return new Response(null, { ...responseInit, headers });
};

/**
Expand Down
10 changes: 5 additions & 5 deletions packages/react-router/lib/types/route-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type {
ClientLoaderFunctionArgs,
ClientActionFunctionArgs,
} from "../dom/ssr/routeModules";
import type { DataWithResponseInit, Redirect } from "../router/utils";
import type { DataWithResponseInit } from "../router/utils";
import type { Serializable } from "../server-runtime/single-fetch";
import type { Equal, Expect, Func, IsAny, Pretty } from "./utils";

Expand Down Expand Up @@ -44,13 +44,13 @@ type DataFrom<T> =

// prettier-ignore
type ClientData<T> =
T extends Redirect ? never :
T extends Response ? never :
T extends DataWithResponseInit<infer U> ? U :
T

// prettier-ignore
type ServerData<T> =
T extends Redirect ? never :
T extends Response ? never :
T extends DataWithResponseInit<infer U> ? Serialize<U> :
Serialize<T>

Expand Down Expand Up @@ -86,7 +86,7 @@ type __tests = [
| { data: string; b: Date; c: undefined }
>
>,
Expect<Equal<ServerDataFrom<() => { a: string } | Redirect>, { a: string }>>,
Expect<Equal<ServerDataFrom<() => { a: string } | Response>, { a: string }>>,

// ClientDataFrom
Expect<Equal<ClientDataFrom<any>, undefined>>,
Expand All @@ -109,5 +109,5 @@ type __tests = [
| { data: string; b: Date; c: () => boolean }
>
>,
Expect<Equal<ClientDataFrom<() => { a: string } | Redirect>, { a: string }>>
Expect<Equal<ClientDataFrom<() => { a: string } | Response>, { a: string }>>
];

0 comments on commit 372e25f

Please sign in to comment.