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!
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.
I had same error using fetch in an angular (typescript) project, I could solve it by declaring fetch like this:
  declare var fetch;
                        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/**/*",
  ]
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With