Skip to content

Inferred type of loader/action data from typegen is incorrect when loader/action returns explicitly typed data #13083

Closed
@harrygr

Description

@harrygr

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.

Image

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions