Skip to content

TypeScript error: inferred type of 'useMutate' cannot be named without a reference to 'swr-openapi/node_modules/type-fest' #2240

Open
@andreafra

Description

@andreafra

swr-openapi version

5.1.4

Description

Hi,

I'm using openapi-fetch + swr-openapi in a TypeScript project (standard Vite configuration), and I get the following TypeScript error in my code:

// rest of client config

export const useQuery = createQueryHook(client, 'agenda-api')
export const useImmutable = createImmutableHook(client, prefix)
export const useInfinite = createInfiniteHook(client, prefix)
// TS-ERROR:
// The inferred type of 'useMutate' cannot be named without a reference to 'swr-openapi/node_modules/type-fest'. 
// This is likely not portable. A type annotation is necessary.
export const useMutate = createMutateHook(
  client,
  prefix,
  isMatch // Or any comparision function
)

Of course, I don't have type-fest directly in my dependencies, but it gets installed transitively by swr-openapi.

What could be possible solutions to this problem?

Possible solutions

  1. Of course, annotating useMutate: (...args: any[]) => any may work, but it's not useful, otherwise I'd be using JavaScript.

  2. So far, as a workaround, I've added as a custom type a reimplementation of the value returned by createMutateHook:

export const useQuery = createQueryHook(client, 'agenda-api')
export const useImmutable = createImmutableHook(client, prefix)
export const useInfinite = createInfiniteHook(client, prefix)
export const useMutate = createMutateHook(
  client,
  prefix,
  isMatch // Or any comparision function
) as UseMutate<paths>

// This is a very stupid hack to make useMutate work.
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
type UseMutate<Paths extends {}> = () => <
  Path extends PathsWithMethod<Paths, 'get'>,
  R extends TypesForGetRequest<Paths, Path>,
  Init extends R['Init']
>(
  [path, init]: [Path, PartialDeep<Init>?],
  data?: R['Data'] | Promise<R['Data']> | MutatorCallback<R['Data']>,
  opts?: boolean | MutatorOptions<R['Data']>
) => Promise<(R['Data'] | undefined)[]>

Is (2) the expected solution (doubt it), or would re-exporting type-fest from swr-openapi be a solution?

I'd gladly look more into it, but I'm afraid I currently don't have the time...

Reproduction

This is the complete file:

import type { paths } from '@lib/api/types/schema'
import { API_BASE_PATH } from '@lib/constants'

import isMatch from 'lodash-es/isMatch'
import createClient, { type Middleware } from 'openapi-fetch'
import {
  createImmutableHook,
  createInfiniteHook,
  createMutateHook,
  createQueryHook
} from 'swr-openapi'

const client = createClient<paths>({
  baseUrl: API_BASE_PATH
})

const oauthMiddleware: Middleware = {
  // ...
}

// register middleware
client.use(oauthMiddleware)

export { client }

const prefix = 'my-api'

export const useQuery = createQueryHook(client, prefix)
export const useImmutable = createImmutableHook(client, prefix)
export const useInfinite = createInfiniteHook(client, prefix)
export const useMutate: () => unknown = createMutateHook(
  client,
  prefix,
  isMatch // Or any comparision function
)

Expected result

TypeScript raises the following error during build (or in IDE):

The inferred type of 'useMutate' cannot be named without a reference to 'swr-openapi/node_modules/type-fest'.
This is likely not portable. A type annotation is necessary.

Extra

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingswr-openapiRelevant to swr-openapi library

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions