Update:
My original post below is all true. I have been able to get it to work, however, without having to switch to ESM modules. Here is what's working in my code (based on the third code snippet in the following post: https://github.com/node-fetch/node-fetch/issues/1279#issuecomment-915063354)
// eslint-disable-next-line no-new-func
const importDynamic = new Function('modulePath', 'return import(modulePath)');
const fetch = async (...args:any[]) => {
const module = await importDynamic('node-fetch');
return module.default(...args);
};
Original Post:
The Cannot redeclare block-scoped variable 'fetch'
error is because you're declaring a const fetch
variable, and then reusing the name "fetch
" as the object-destructured parameter to the then()
callback later in the line.
So, changing the line to read as follows clears up that error:
const fetch = (...args) => import("node-fetch").then(module => module.default(...args));
As for the other error (A spread argument must either have a tuple type or be passed to a rest parameter.
), one possible way to solve this would be to actually import the correct argument types for the fetch()
call, then substitute in the above code snippet as appropriate, like this:
import { RequestInfo, RequestInit } from 'node-fetch';
const fetch = (url:RequestInfo, init?:RequestInit) => import('node-fetch').then(module => module.default(url, init));
Unfortunately, while that seems to satisfy the TypeScript compiler, I'm finding in my own code that the runtime still doesn't work (throws an ERR_REQUIRE_ESM
) because my TypeScript config is currently using CommonJS modules rather than an ESM format.
See https://github.com/node-fetch/node-fetch/issues?q=ERR_REQUIRE_ESM for several open issues in the node-fetch package related to this problem.
Essentially, the node-fetch maintainers are suggesting those of us using TypeScript need to convert to ESM modules, away from CommonJS (see https://github.com/node-fetch/node-fetch/issues/1397#issuecomment-978092116 and subsequent comments).