swr icon indicating copy to clipboard operation
swr copied to clipboard

When the fetcher function is generic the concrete type is not inferred

Open phaux opened this issue 1 year ago • 0 comments

Bug report

Description / Observed Behavior

import useSWR from "swr"

async function fetcher<T extends string>(args: readonly [T]): Promise<T> {
  return args[0]
}

function App() {
  const foo = useSWR(["foo"] as const, fetcher)
  if (foo.data != null) {
    // `foo.data` should be of type "foo" but is string
  }
}

Expected Behavior

Same thing with react-query works as expected:

import { useQuery } from "@tanstack/react-query"

async function fetcher<T extends string>(context: { queryKey: readonly [T] }): Promise<T> {
  return context.queryKey[0]
}

function App() {
  const bar = useQuery(["bar"] as const, fetcher)
  if (bar.data != null) {
    // `bar.data` is of type "bar"
  }
}

Additional Context

SWR version: 2.0.0-beta.6

Workaround

For some reason if we create a generic getFetcher function which returns the actual fetcher, then it works:

import useSWR from "swr"

function getFetcher<T extends string>(): (args: readonly [T]) => Promise<T> {
  return async (args) => {
    return args[0]
  }
}

function App() {
  const foo = useSWR(["foo"] as const, getFetcher())
  if (foo.data != null) {
    // `foo.data` is "foo"
  }
}

phaux avatar Aug 17 '22 21:08 phaux