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