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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.