15

I'm aiming to build a Typescript library with AJAX calls (by using the fetch API), that can be used by both client-side (Webpack/Browserify) and back-end developers (Node).

However, I can't seem to get the fetch to compile without errors.


My first attempt has been with isomorphic-fetch and @types/isomorphic-fetch. I'm unsure whether the types are complete, but they didn't bring any global variable (they should be bringing fetch, shouldn't they?).

npm i isomorphic-fetch @types/isomorphic-fetch

index.ts

import 'isomorphic-fetch';
export function execute() {
  return fetch('...') ...
}

tsconfig.json

"compilerOptions": {
  ...
  "lib": ["es2015", "es2016", "es2017"]
}

Output:

node_modules/@types/isomorphic-fetch/index.d.ts(8,30): error TS2304: Cannot find name 'fetch'.
src/index.ts(4,25): error TS2304: Cannot find name 'fetch'.

Do I need "dom"? Apparently, with the dom lib it does compile and work on both ✓, but I got no control on whether it will actually work on Node. I mean, it will compile whether or not I import 'isomorphic-fetch', but if I miss it in will fail on Node without notice.

Also, Node is not "dom", regardless of me wanting to support browsers as well.


My second attempt has been with whatwg-fetch.

npm i whatwg-fetch @types/whatwg-fetch

tsconfig.json

"lib": ["es2015", "es2016", "es2017"] // The same.

This one doesn't even pass the compilation phase (regardless of the "dom" library):

> tsc --watch

node_modules/@types/whatwg-fetch/index.d.ts(11,27): error TS2304: Cannot find name 'window'.
node_modules/@types/whatwg-fetch/index.d.ts(31,25): error TS2304: Cannot find name 'Blob'.
node_modules/@types/whatwg-fetch/index.d.ts(31,64): error TS2304: Cannot find name 'FormData'.
node_modules/@types/whatwg-fetch/index.d.ts(36,21): error TS2304: Cannot find name 'Blob'.
node_modules/@types/whatwg-fetch/index.d.ts(37,25): error TS2304: Cannot find name 'FormData'.
17:31:50 - Compilation complete. Watching for file changes.

With "dom":

node_modules/typescript/lib/lib.dom.d.ts(9353,11): error TS2300: Duplicate identifier 'Request'.
node_modules/typescript/lib/lib.dom.d.ts(9370,13): error TS2300: Duplicate identifier 'Request'.
node_modules/typescript/lib/lib.dom.d.ts(9375,11): error TS2300: Duplicate identifier 'Response'.
node_modules/typescript/lib/lib.dom.d.ts(9386,13): error TS2300: Duplicate identifier 'Response'.
node_modules/typescript/lib/lib.dom.d.ts(14940,18): error TS2451: Cannot redeclare block-scoped variable 'fetch'.
node_modules/typescript/lib/lib.dom.d.ts(14945,6): error TS2300: Duplicate identifier 'BodyInit'.
node_modules/typescript/lib/lib.dom.d.ts(14966,6): error TS2300: Duplicate identifier 'HeadersInit'.
node_modules/typescript/lib/lib.dom.d.ts(14976,6): error TS2300: Duplicate identifier 'RequestInfo'.
node_modules/typescript/lib/lib.dom.d.ts(15043,6): error TS2300: Duplicate identifier 'ReferrerPolicy'.
node_modules/typescript/lib/lib.dom.d.ts(15044,6): error TS2300: Duplicate identifier 'RequestCache'.
node_modules/typescript/lib/lib.dom.d.ts(15045,6): error TS2300: Duplicate identifier 'RequestCredentials'.
node_modules/typescript/lib/lib.dom.d.ts(15046,6): error TS2300: Duplicate identifier 'RequestDestination'.
node_modules/typescript/lib/lib.dom.d.ts(15047,6): error TS2300: Duplicate identifier 'RequestMode'.
node_modules/typescript/lib/lib.dom.d.ts(15048,6): error TS2300: Duplicate identifier 'RequestRedirect'.
node_modules/typescript/lib/lib.dom.d.ts(15049,6): error TS2300: Duplicate identifier 'RequestType'.
node_modules/typescript/lib/lib.dom.d.ts(15050,6): error TS2300: Duplicate identifier 'ResponseType'.
...

I've also attempted with other similar libraries such as fetch-ponyfill, but this one doesn't even have types available for TypeScript.


How are we supposed to call fetch on a universal application (browser + Node)?

Thanks!

5
  • Did you take a look at github.com/matthew-andrews/isomorphic-fetch ? Commented Jul 8, 2017 at 16:32
  • @TomaszBubała I did. That's the case #1, but apparently, it doesn't compile without errors without the dom library (which I guess it's only meant to be used in browser-only libraries) :/ Commented Jul 8, 2017 at 16:36
  • It's not a direct answer to what you need, but you may abstract out fetch as in clean architecture: 8thlight.com/blog/uncle-bob/2012/08/13/… Commented Jul 9, 2017 at 8:37
  • It's 2023 and isomorphic-fetch still doesn't work for me unless I add the dom library to my tsconfig (which is a no go for server-side). I just don't get it - isn't the point of this to bring fetch both server-side and browser-side? Commented Feb 17, 2023 at 14:20
  • Definitely skim through github.com/Microsoft/TypeScript/issues/4948 . Bottom line: It's a mess. Commented Aug 17, 2023 at 9:00

4 Answers 4

10

To get proper type definitions you have a couple options.

If your TypeScript will be running in the browser:

Add the built-in "DOM" to your compiler libs (either with the --lib command line compiler option or to lib in tsconfig.json). Adding "DOM" to libs is probably the right option if you're TypeScript will be running in a modern browser. However, if you're TypeScript is running in a non-browser environment with a fetch module check Option 2.

If your TypeScript will be running on the server (node.js):

If you're using a library like node-fetch on node, then add the @types/node-fetch type definitions, and import fetch like import fetch from "node-fetch"

If your TypeScript is running in both browser and server (e.g. for a server-side rendering project) import the DOM lib and you probably want to add the isomorphic-fetch package.

Sign up to request clarification or add additional context in comments.

Comments

4

I had same error using fetch in an angular (typescript) project, I could solve it by declaring fetch like this:

  declare var fetch;

1 Comment

declare const fetch: Function
2

If you are transpiling with the below command:

"ts-watch": "tsc file1.ts file2.ts --watch"

Then remove the individual file declarations and it should work if you have a valid tsconfig.json:

"ts-watch": "tsc --watch"

Here is an example of a working tsconfig:

{
  "compilerOptions": {
    "outDir": "lib",
    "sourceMap": true,
    "noImplicitAny": true,
    "lib": [
      "ES2015",
      "DOM"
    ],
    "module": "esnext",
    "target": "ES2015",
    "strict": true,
    "jsx": "react",
    "allowJs": true,
    "declaration": true,
    "moduleResolution": "node",
    "typeRoots": [
      "node_modules/@types/",
      "index.d.ts"
    ],
    "esModuleInterop": true
  },
  "include": [
    "./typescript/**/*",
  ]
}

Comments

1

Installing @types/node version 20.8.4 or later solves this.

npm install --save-dev @types/node@">=20.8.4"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.