Got: Duplicate identifier `URLSearchParams` and `URL` in compiling `[email protected]` with `[email protected]`

Created on 9 Dec 2019  Â·  11Comments  Â·  Source: sindresorhus/got

Describe the bug

  • Node.js version: v12.13.0
  • OS & version: MacOS 10.14.6

Error in compiling [email protected] with [email protected]. Duplicate identifier 'URLSearchParams' and Duplicate identifier 'URL'. No issues with [email protected] and [email protected]

Actual behavior

Below the errors that tsc compiler reports:

node_modules/got/dist/source/utils/types.d.ts:182:11 - error TS2300: Duplicate identifier 'URL'.

182     class URL {
              ~~~

  node_modules/typescript/lib/lib.dom.d.ts:16052:11
    16052 interface URL {
                    ~~~
    'URL' was also declared here.
  node_modules/typescript/lib/lib.dom.d.ts:16068:13
    16068 declare var URL: {
                      ~~~
    and here.

node_modules/got/dist/source/utils/types.d.ts:199:11 - error TS2300: Duplicate identifier 'URLSearchParams'.

199     class URLSearchParams implements Iterable<[string, string]> {
              ~~~~~~~~~~~~~~~

  node_modules/typescript/lib/lib.dom.d.ts:16078:11
    16078 interface URLSearchParams {
                    ~~~~~~~~~~~~~~~
    'URLSearchParams' was also declared here.
  node_modules/typescript/lib/lib.dom.d.ts:16107:13
    16107 declare var URLSearchParams: {
                      ~~~~~~~~~~~~~~~
    and here.
  node_modules/typescript/lib/lib.dom.iterable.d.ts:263:11
    263 interface URLSearchParams {
                  ~~~~~~~~~~~~~~~
    and here.

node_modules/typescript/lib/lib.dom.d.ts:16052:11 - error TS2300: Duplicate identifier 'URL'.

16052 interface URL {
                ~~~

  node_modules/got/dist/source/utils/types.d.ts:182:11
    182     class URL {
                  ~~~
    'URL' was also declared here.

node_modules/typescript/lib/lib.dom.d.ts:16068:13 - error TS2300: Duplicate identifier 'URL'.

16068 declare var URL: {
                  ~~~

  node_modules/got/dist/source/utils/types.d.ts:182:11
    182     class URL {
                  ~~~
    'URL' was also declared here.

node_modules/typescript/lib/lib.dom.d.ts:16078:11 - error TS2300: Duplicate identifier 'URLSearchParams'.

16078 interface URLSearchParams {
                ~~~~~~~~~~~~~~~

  node_modules/got/dist/source/utils/types.d.ts:199:11
    199     class URLSearchParams implements Iterable<[string, string]> {
                  ~~~~~~~~~~~~~~~
    'URLSearchParams' was also declared here.

node_modules/typescript/lib/lib.dom.d.ts:16107:13 - error TS2300: Duplicate identifier 'URLSearchParams'.

16107 declare var URLSearchParams: {
                  ~~~~~~~~~~~~~~~

  node_modules/got/dist/source/utils/types.d.ts:199:11
    199     class URLSearchParams implements Iterable<[string, string]> {
                  ~~~~~~~~~~~~~~~
    'URLSearchParams' was also declared here.

node_modules/typescript/lib/lib.dom.iterable.d.ts:263:11 - error TS2300: Duplicate identifier 'URLSearchParams'.

263 interface URLSearchParams {
              ~~~~~~~~~~~~~~~

  node_modules/got/dist/source/utils/types.d.ts:199:11
    199     class URLSearchParams implements Iterable<[string, string]> {
                  ~~~~~~~~~~~~~~~
    'URLSearchParams' was also declared here.

Expected behavior

Compile with no errors.

Code to reproduce

package.json

{
  ...
  "scripts": {
    "build": "tsc",
  },
  "dependencies": {
    "got": "10.0.2"
  },
  "devDependencies": {
    "typescript": "3.7.3"
  }
  ...
}

index.ts

import got from "got";
console.log(got);

tsconfig.json
Standard config generated by npx tsc --init

Run npm run build to see errors.

Checklist

  • [ ] I have read the documentation.
  • [ ] I have tried my code with the latest version of Node.js and Got.
bug types ✭ help wanted ✭

All 11 comments

@kirillgroshkov
Mind sharing your tsconfig?

@szmarczak @sindresorhus we might have to document in the README to tell people to manually exclude dom from their TS environment before this is fixed upstream. I will try to draft something tonight.

My tsconfig.json:

{
  "extends": "@naturalcycles/dev-lib/cfg/tsconfig.json",
  "compilerOptions": {
    "outDir": "dist"
  },
  "include": ["src"],
  "exclude": ["**/__exclude"]
}

@naturalcycles/dev-lib/cfg/tsconfig.json is:

//
// @naturalcycles/dev-lib/cfg/tsconfig.json
//
// Shared tsconfig for Node.js projects
//
{
  "compilerOptions": {
    // Disabled because of https://github.com/Microsoft/TypeScript/issues/29172
    // "outDir": "dist",
    // "rootDir": "./src",

    // Target/module
    "target": "es2018",
    "lib": ["es2018"], // add "dom" if needed
    "module": "commonjs",
    "moduleResolution": "node",

    // Emit
    "sourceMap": false,
    "declaration": false,

    // Strictness
    "strict": true,
    "noFallthroughCasesInSwitch": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "suppressImplicitAnyIndexErrors": true,

    // todo: monitor if we should have it default or not
    // Enabled should be faster, but will catch less errors
    // "skipLibCheck": true,

    // Need to be specified in the project tsconfig
    // "typeRoots": [
    //   "node_modules/@types",
    //   "src/@types"
    // ],

    // Other
    "pretty": true,
    "newLine": "lf",
    "importHelpers": true,
    "experimentalDecorators": true
  }
  // Need to be specified in the project tsconfig
  // "include": ["src"],
  // "exclude": ["**/__exclude"]
}

@pmmmwh @sindresorhus I think we should revert to using

import {URL} from 'url'; // TODO: remove this when TypeScript gets merged

The issue is that, by default tsc init with a target of ES5/ES6, which yields the libraries DOM,ES5,ScriptHost and DOM,ES6,DOM.Iterable,ScriptHost. The DOM library includes the URL global type (window.URL), which is incompatible with the Node.js version of the global. To deal with the missing global type from upstream (DefinitelyTyped), we added a shim to provide that, but because the signatures does not overlap, and it is a duplicated identifier on the global scope, TypeScript will get confused and error out.

To fix that, omit DOM explicitly from your list of libraries.

@szmarczak Does url.URL equals to URL in terms of functionality?

IMO yes, it does.

A side note: please don't quote the whole issue, that's unnecessary :wink:

IMO yes, it does.

A side note: please don't quote the whole issue, that's unnecessary 😉

I guess it's up to you / @sindresorhus to see if we're going to use that last resort then.

(Sorry I just clicked quote randomly 🤣 )

I'm not as experienced as @sindresorhus, so I guess it's up to him.

Telling people to modify their tsconfig is not going to be feasible. People are not going to read it and we'll continue to get issues about this and also, Got might be a deep dependency. I guess our only option is to go back to explicitly importing URL and URLSearchParams...

TypeScript is such a mess.

@pmmmwh How could you

omit DOM explicitly from your list of libraries.

I've tried different combinations of target and lib and typescript always included that lib.dom.

Maybe it's desirable to just rename your own global declaration from URL and URLSearchParams to something else or just import it from lib.dom since this getting imported by default anyways?

Telling people to modify their tsconfig is not going to be feasible. People are not going to read it and we'll continue to get issues about this and also, Got might be a deep dependency. I guess our only option is to go back to explicitly importing URL and URLSearchParams...

TypeScript is such a mess.

I used to never understand that sentiment, but now I feel the pain.
Fixing this through a PR soon (again).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

khizarsonu picture khizarsonu  Â·  3Comments

darksabrefr picture darksabrefr  Â·  3Comments

quocnguyen picture quocnguyen  Â·  4Comments

astoilkov picture astoilkov  Â·  3Comments

lukechu10 picture lukechu10  Â·  3Comments