Create-react-app: serviceWorker.ts typescript compilation fail with @types/node": "^13.13.0

Created on 19 Apr 2020  Â·  9Comments  Â·  Source: facebook/create-react-app

Describe the bug

serviceWorker.ts created bye CRA using typescript template generate a compilation compilation error if you upgrade nodejs typedefs with @types/node": "^13.13.0

The problem can be resolved using @types/node": "^12.12.36 but I think it is more correct to define the behavior in case URL is null for the future.

Did you try recovering your dependencies?

Yes

npm --version
6.14.4

Which terms did you search for in User Guide?

"create-react-app" serviceWorker typescript compilation fail

Environment

npx create-react-app --info
npx: installed 99 in 4.647s

Environment Info:

  current version of create-react-app: 3.4.1
  running from /home/ev/.npm/_npx/21142/lib/node_modules/create-react-app

  System:
    OS: Linux 5.3 Ubuntu 18.04.4 LTS (Bionic Beaver)
    CPU: (8) x64 Intel(R) Core(TM) i7-3840QM CPU @ 2.80GHz
  Binaries:
    Node: 12.16.1 - ~/.nvm/versions/node/v12.16.1/bin/node
    Yarn: Not Found
    npm: 6.14.4 - ~/.nvm/versions/node/v12.16.1/bin/npm
  Browsers:
    Chrome: 81.0.4044.113
    Firefox: 75.0
  npmPackages:
    react: Not Found
    react-dom: Not Found
    react-scripts: Not Found
  npmGlobalPackages:
    create-react-app: Not Found

Steps to reproduce

npx create-react-app test01 --template typescript
cd test01
npm i @types/[email protected]
npm run build

Expected behavior

In your code if you type new URL(param) param must be a valid string but if you set param as process.env.PUBLIC_URL this could be undefined.

Actual behavior

TypeScript error in .../src/serviceWorker.ts(32,7):
Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
  Type 'undefined' is not assignable to type 'string'.  TS2345

    30 |     // The URL constructor is available in all browsers that support SW.
    31 |     const publicUrl = new URL(
  > 32 |       process.env.PUBLIC_URL,
       |       ^
    33 |       window.location.href
    34 |     );
    35 |     if (publicUrl.origin !== window.location.origin) {

Reproducible demo

Follow the instructions given in point [Steps to reproduce]

bug report needs triage

All 9 comments

You can use temporary workaround – add ! to process.env.PUBLIC_URL. It works for me

Zrzut ekranu 2020-04-19 o 18 01 33

If you don't want to use ! or your linters doesn't let you use !. You can do it simply this way:

// serviceWorker.ts

...
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator && process.env.PUBLIC_URL) {
    // The URL constructor is available in all browsers that support SW.
    const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
    ...
}
...

Thank you! I was not looking for a workaround to avoid the compilation problem but the right way to proceed in case of process.env.PUBLIC_URL has been null.
My personal solution to solve the problem was using process.env.PUBLIC_URL || "" but I think the one suggested by @bartlomiejzuber is better.

I'm having the same issue but in a NextJS project.

It seems @types/node now merges my env.d.ts but says it can be either what I'd defined or undefined:

Screenshot 2020-04-20 at 14 47 45

Screenshot 2020-04-20 at 14 48 15

@raulfdm I don't know NextJS but I don't think it uses CRA as I described above.
The instructions I see are completely different.
Can you please specify the steps you took to get the same problem?

@raulfdm I don't know NextJS but I don't think it uses CRA as I described above.
The instructions I see are completely different.
Can you please specify the steps you took to get the same problem?

Unfortutanely it's a private project but basically I have defined a .env.d.ts like:

declare global {
  namespace NodeJS {
    interface ProcessEnv {
      NODE_ENV: string;
      APP_ENV: string;
      STATIC_HOST: string;
      // ... etc
    }
  }
}

export {};

Which in my current @types/[email protected] allow me to use everywhere node environment variables without problems (e.g.):

    const domain = process.env.WEB_CLIENT_HOST.includes(':')
        ? process.env.WEB_CLIENT_HOST.split(':')[0]
        : `.${process.env.WEB_CLIENT_HOST}`;

But with @types/[email protected] now Typescript complains about all those custom variables might be undefined, which forces me to use such solution as @JB1905 mentioned (!).

@erosval just to be clear, my comment was about having the exactly same issue in a different kind of project, which probably means the problem isn't from CRA but from @types/[email protected]

@raulfdm @erosval I see that root cause of this issue is already tracked here https://github.com/DefinitelyTyped/DefinitelyTyped/pull/44003, therefore if they decide to revert, there will be no longer any fix required.

thank you @bartlomiejzuber, this solve the question!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wereHamster picture wereHamster  Â·  3Comments

rdamian3 picture rdamian3  Â·  3Comments

jnachtigall picture jnachtigall  Â·  3Comments

DaveLindberg picture DaveLindberg  Â·  3Comments

Aranir picture Aranir  Â·  3Comments