remix: v2pre ts bug, not happy with typed const arrow functions

What version of Remix are you using?

2.0.0-pre.2

Are all your remix dependencies & dev-dependencies using the same version?

  • Yes

Steps to Reproduce

Upgrading to v2 release candidate from v1.19.3 is fairly painless on mana.wiki, except for this one weird Typescript error that I don’t know what might be the sourced from:

image

$ remix dev -c "npm run dev:node" --manual

 💿  remix dev

 info  building...
X [ERROR] The character ">" is not valid inside a JSX element

    app/utils/swr-fetchers.ts:25:48:
      25 │ export const swrGqlFetcher = <T>(props: Props) => {
         ╵                                                 ^

  TypeScript's TSX syntax interprets arrow functions with a single generic type parameter as an opening JSX element. If you want it to be interpreted as an arrow function instead, you need to add a trailing comma after the type parameter to 
disambiguate:

    app/utils/swr-fetchers.ts:25:29:
      25 │ export const swrGqlFetcher = <T>(props: Props) => {
         │                              ~~~
         ╵                              <T,>


X [ERROR] Unexpected "const"

    app/utils/swr-fetchers.ts:26:3:
      26 │    const { query, variables } = props;
         ╵    ~~~~~


 info  rebuilding... (~ app\utils\swr-fetchers.ts)
 info  building...
X [ERROR] The character ">" is not valid inside a JSX element

    app/utils/swr-fetchers.ts:26:48:
      26 │ export const swrGqlFetcher = <T>(props: Props) => {
         ╵                                                 ^

  TypeScript's TSX syntax interprets arrow functions with a single generic type parameter as an opening JSX element. If you want it to be interpreted as an arrow function instead, you need to add a trailing comma after the type parameter to 
disambiguate:

    app/utils/swr-fetchers.ts:26:29:
      26 │ export const swrGqlFetcher = <T>(props: Props) => {
         │                              ~~~
         ╵                              <T,>


X [ERROR] Unexpected "const"

    app/utils/swr-fetchers.ts:27:3:
      27 │    const { query, variables } = props;
         ╵    ~~~~~


 info  rebuilding... (~ app\utils\swr-fetchers.ts)

Updating the .ts files so they don’t use arrow functions got the build working, otherwise, great release!

Expected Behavior

Remix shouldn’t have an opinion about how I declare functions in typescript files.

Actual Behavior

Remix is very insistent on me stop using const arrow functions.

About this issue

  • Original URL
  • State: closed
  • Created 10 months ago
  • Comments: 28 (24 by maintainers)

Commits related to this issue

Most upvoted comments

@pcattori so what you’re saying is we’re idiots 🤣 (for anyone reading this in the future, it’s a joke)

@AlemTuzlak Setting **/* in ignoredRoutePatterns will make Remix ignore all of your route files, which only prevents the error by not processing any routes.

@xHomu Needing to disambiguate single-arg generics from JSX elements has been a thing in TS for a long time. Here’s a playground repro: https://tsplay.dev/w6Vqyw . Note that changing the TS version to anything (3.3-5.2) results in the same error.

To fix your code, you don’t have to remove arrow functions. You can put a comma after the T (or whatever type generic) as indicated in the error message: https://tsplay.dev/WPBJkN

Not sure why you’d only run into this in v2 and not 1.19.3, but maybe we fixed something in the compiler to be more TS compliant. But I’d argue that’s a feature, not a bug.

@pcattori isn’t that the whole reason we have .ts and .tsx files, though? (to disambiguate JSX vs non-JSX files)

Looking at the screen @xHomu posted, the compiler is parsing a .ts as a JSX file, which is the real bug here.

Well, he’s not wrong!

@xHomu I have the same issue, created a minimum repro here: https://github.com/AlemTuzlak/remix-v2-ts-issue You can reproduce this issue by cloning my repo, installing the deps and running npm run dev. The issue seems to be with the remix.config.js, If you add the following to ignoredRouteFiles:

const ignoredRoutePatterns = [
  "**/.*",
  "**/components/**",
  "**/integration/*.test.*",
];

module.exports = { 
  ignoredRouteFiles: ignoredRoutePatterns,
  serverDependenciesToBundle: [/^marked.*/],
  tailwind: true,
  serverModuleFormat: "cjs",
};

it breaks, but if you do the following:

const ignoredRoutePatterns = [
-  "**/.*",
+ "**/*",
  "**/components/**",
  "**/integration/*.test.*",
];

module.exports = { 
  ignoredRouteFiles: ignoredRoutePatterns,
  serverDependenciesToBundle: [/^marked.*/],
  tailwind: true,
  serverModuleFormat: "cjs",
};

it works