Applying stolen fetch types to redefine urql Client fetch member doesn't satisfy Typescript

86 Views Asked by At

I'm having a hard time trying to satisfy Typescript when redefining the fetch function on @urql/core.

I found two SO answers that kind of nailed the problem, but somehow they doesn't work for me:

My code looks like this:

import { Client } from "@urql/core"

const client = new Client({
  fetch: async (...args: Parameters<typeof fetch>) => {
    const response = await fetch(...args);
// ...

And the Typescript complaint is:

error| Type '(input: RequestInfo, init?: RequestInit | undefined) => Promise' is not assignable to type '{ (input: RequestInfo | URL, init?: RequestInit | undefined): Promise; (input: RequestInfo, init?: RequestInit | undefined): Promise<...>; }'. Types of parameters 'input' and 'input' are incompatible. Type 'RequestInfo | URL' is not assignable to type 'RequestInfo'. Type 'Request' is not assignable to type 'RequestInfo'. Property 'duplex' is missing in type 'Request' but required in type 'import("./node_modules/undici-types/fetch").Request'.

(path slightly edited to hide personal information)

I tried a simplified fetch replacement just to seek how to satisfy Typescript, and found that this code works fine:

const fetcher = async (...args: Parameters<typeof fetch>) => {
  const response = await fetch(...args)
  // ...
  return response
}

While this one gives me the exact same error as the initial snippet from above:

const originalFetch = global.fetch

global.fetch = async (...args: Parameters<typeof global.fetch>) => {
  const response = await originalFetch(...args)
  // ...
  return response
}

My main question is how to solve this issue and satisfy Typescript.

I tried different things before reaching for Parameters<> and every single attempt gave me a different Typescript error:

// The initial wasn't typed
global.fetch = async (...args) => {
  const response = await originalFetch(...args)
// No overload matches this call

// Secondly used the very same parameters shown on previous attempt error message
global.fetch = async (...args: [RequestInfo | URL, RequestInit | undefined]) => {
  const response = await originalFetch(...args)
// but then it complains about missing property 'referrer' from the `undici` type

// Thirdly I removed the `URL` option from the first parameter
global.fetch = async (...args: [RequestInfo, RequestInit | undefined]) => {
  const response = await originalFetch(...args)
// but it seems is needed cause "Type 'RequestInfo | URL' is not assignable to type 'RequestInfo'"

It's really puzzling seeing it working fine when I assign to whatever name, but breaking when trying to overwrite the global function. Since I'm trying to tamper with response data from @urql/core, I cannot use another method as I have to replace the fetch member from Client.

0

There are 0 best solutions below