Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript - Cannot find name 'fetch' (universal library)

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!

like image 340
zurfyx Avatar asked Jul 08 '17 15:07

zurfyx


3 Answers

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.

like image 200
Scott Willeke Avatar answered Nov 17 '22 20:11

Scott Willeke


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

  declare var fetch;
like image 26
Sheki Avatar answered Nov 17 '22 20:11

Sheki


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/**/*",
  ]
}
like image 1
Joe Gasewicz Avatar answered Nov 17 '22 19:11

Joe Gasewicz