Closed
Description
I'm using React Router as a...
framework
Reproduction
https://stackblitz.com/edit/github-5hxqgqbv?file=app%2Froutes%2Fhome.tsx
Example:
import { Route } from "./+types/test";
interface Result {
errors?: Record<string, string>;
result: string;
}
const getResult = (n: number): Result => {
if (n > 0.5) {
return { result: "ok", errors: { foo: "bar" } };
}
return { result: "bad" };
};
export const action = async () => {
return getResult(1);
};
export const loader = async () => {
return getResult(0.1);
};
export const Component = ({ actionData, loaderData }: Route.ComponentProps) => {
actionData?.errors; // unknown, should be Record<string, string> | undefined
loaderData.errors; // unknown, should be Record<string, string> | undefined
return <div></div>;
};
System Info
System:
OS: macOS 15.3.1
CPU: (12) arm64 Apple M2 Pro
Memory: 86.84 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.11.1 - ~/.nvm/versions/node/v20.11.1/bin/node
Yarn: 1.22.19 - ~/.nvm/versions/node/v20.11.1/bin/yarn
npm: 10.2.4 - ~/.nvm/versions/node/v20.11.1/bin/npm
pnpm: 9.15.3 - ~/.nvm/versions/node/v20.11.1/bin/pnpm
Browsers:
Chrome: 133.0.6943.55
Safari: 18.3
npmPackages:
@react-router/dev: ^7.1.5 => 7.2.0
@react-router/fs-routes: ^7.1.5 => 7.2.0
@react-router/serve: ^7.1.5 => 7.2.0
react-router: ^7.1.5 => 7.2.0
vite: ^5.4.11 => 5.4.14
Used Package Manager
npm
Expected Behavior
When an action or loader returns data from a function that declares its return type the action/loader data should have the correct type.
Actual Behavior
In the case of the example, the error
property is unknown
, despite it being typed as Record<string,string>
in the Result
type.

Note: This is a regression introduced in react-router 7.2. 7.1 behaves correctly.