Skip to content

RR7 typegen doesn't support moduleResolution node16 #12424

Closed
@octet-stream

Description

@octet-stream

I'm using React Router as a...

framework

Reproduction

https://stackblitz.com/edit/rr7-typegen-node16-support-issue?file=app%2Froutes%2Fhello.%24name.tsx

Just open the app/routes/hello.$name.tsx file and look at the loaderData type. You'll see it is correct. Then open tsconfig.json and set moduleResolution to node16, and then return to previous file. Now loaderData is undefined.

System Info

System:
    OS: macOS 15.1.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 187.33 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 23.1.0 - ~/.local/state/fnm_multishells/42293_1732447663469/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 10.9.0 - ~/.local/state/fnm_multishells/42293_1732447663469/bin/npm
    pnpm: 9.14.1 - /opt/homebrew/bin/pnpm
    bun: 1.1.34 - /run/current-system/sw/bin/bun
  Browsers:
    Chrome: 131.0.6778.86
    Safari: 18.1.1
  npmPackages:
    @react-router/dev: ^7.0.1 => 7.0.1
    @react-router/fs-routes: 7.0.1 => 7.0.1
    @react-router/node: ^7.0.1 => 7.0.1
    @react-router/serve: ^7.0.1 => 7.0.1
    react-router: ^7.0.1 => 7.0.1
    vite: ^6.0.1 => 6.0.1

Used Package Manager

pnpm

Expected Behavior

loaderData has correct types when moduleResolution is set to node16. In this case - it should be a string.

This might not be an issue for the most (I think), but for me - it is, because this is how Node.js resolves ES modules by default and this might be a problem when I have a code that is shared between Vite and Node.js, so I expect this to work.

Actual Behavior

loaderData is of type undefined when moduleResolution is set to node16

This happens because TS expects files to have a .js at the end of module specifier, same way as Node.js does. From what I can tell, the paths generated by RR's Vite plugin for parent routes are incorrect. This code always outputs path without extension:

type Module = typeof import("../${Pathe.filename(route.file)}")

So, I think to solve this problem, it should respect the moduleResolution option from tsconfig.json (and allowImportingTsExtensions to output .ts at the end of the specifier, if enabled).

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions