Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom useFetch type error #27142

Closed
jxk-developer opened this issue May 10, 2024 · 5 comments
Closed

Custom useFetch type error #27142

jxk-developer opened this issue May 10, 2024 · 5 comments

Comments

@jxk-developer
Copy link

Environment

  • Operating System: Darwin
  • Node Version: v20.11.1
  • Nuxt Version: 3.11.2
  • CLI Version: 3.11.1
  • Nitro Version: 2.9.6
  • Package Manager: pnpm@8.5.1
  • Builder: -
  • User Config: devtools, extends, modules, runtimeConfig
  • Runtime Modules: @nuxt/image@1.5.0
  • Build Modules: -

Reproduction

Reproduction url: https://stackblitz.com/edit/github-um9rcm?file=composables%2FuseAppFetch.ts

Describe the bug

I tried to create my custom composable using the link https://nuxt.com/docs/examples/advanced/use-custom-fetch-composable, but I encountered errors related to typing.
In useAppFetch on line 15.

No overload matches this call. Overload 1 of 2, '(request: NitroFetchRequest | Ref<NitroFetchRequest> | (() => NitroFetchRequest), opts?: UseFetchOptions<ResT extends void ? unknown : ResT, ... 4 more ..., ResT extends void ? "get" : AvailableRouterMethod<...>> | undefined): AsyncData<...>', gave the following error. Argument of type 'UseFetchOptions<ResT, ResT, KeysOf<ResT>, null, string & {}, AvailableRouterMethod<string & {}>>' is not assignable to parameter of type 'UseFetchOptions<ResT extends void ? unknown : ResT, ResT extends void ? unknown : ResT, KeysOf<ResT extends void ? unknown : ResT>, null, NitroFetchRequest, ResT extends void ? "get" : AvailableRouterMethod<...>>'. Type 'ResT extends void ? unknown : ResT' is not assignable to type 'ResT'. 'ResT' could be instantiated with an arbitrary type which could be unrelated to 'ResT extends void ? unknown : ResT'. Overload 2 of 2, '(request: NitroFetchRequest | Ref<NitroFetchRequest> | (() => NitroFetchRequest), opts?: UseFetchOptions<ResT extends void ? unknown : ResT, ... 4 more ..., ResT extends void ? "get" : AvailableRouterMethod<...>> | undefined): AsyncData<...>', gave the following error. Argument of type 'UseFetchOptions<ResT, ResT, KeysOf<ResT>, null, string & {}, AvailableRouterMethod<string & {}>>' is not assignable to parameter of type 'UseFetchOptions<ResT extends void ? unknown : ResT, ResT extends void ? unknown : ResT, KeysOf<ResT extends void ? unknown : ResT>, ResT extends void ? unknown : ResT, NitroFetchRequest, ResT extends void ? "get" : AvailableRouterMethod<...>>'. Type 'ResT extends void ? unknown : ResT' is not assignable to type 'ResT'. 'ResT' could be instantiated with an arbitrary type which could be unrelated to 'ResT extends void ? unknown : ResT'.(2769)

Screenshot 2024-05-10 at 11 36 59

Also in app.vue line 5 type error related to 'transform'. But for some reason in stackblitz.com error in app.vue is not displayed. If you copy whole code to VScode it show error.

Type '(res: Todo[]) => string[]' is not assignable to type '_Transform<Todo[], Todo[]>'. Type 'string[]' is not assignable to type 'Todo[] | Promise<Todo[]>'.ts(2322)

Screenshot 2024-05-10 at 11 35 18

It returns transformed value as expected.

Thanks in advance for helping.

Additional context

No response

Logs

No response

Copy link

stackblitz bot commented May 10, 2024

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

@OrlS15
Copy link
Contributor

OrlS15 commented May 11, 2024

Remove <ResT> from useFetch

export function useAppFetch<ResT>(
  request: NitroFetchRequest,
  options: UseFetchOptions<ResT> = {}
) {
  const defaults: typeof options = {
    $fetch: useNuxtApp().$api,
  };

  const params = defu(options, defaults);

  // return useFetch<ResT>(request, params);
  return useFetch(request, params);
}

More info: https://notes.atinux.com/nuxt-custom-fetch

@jxk-developer
Copy link
Author

Remove <ResT> from useFetch

export function useAppFetch<ResT>(
  request: NitroFetchRequest,
  options: UseFetchOptions<ResT> = {}
) {
  const defaults: typeof options = {
    $fetch: useNuxtApp().$api,
  };

  const params = defu(options, defaults);

  // return useFetch<ResT>(request, params);
  return useFetch(request, params);
}

More info: https://notes.atinux.com/nuxt-custom-fetch

Thanks for solution, it fixes type error with custom useFetch, but error with transform still remains.

@OrlS15
Copy link
Contributor

OrlS15 commented May 11, 2024

With transform ResT is the input and DataT is the output, just type the parameter of transform's function and let it infer the output.

// normal useFetch
const { data: todos } = useFetch("/todos", {
  transform: (res: Todo[]) => {
    return res.map((todo) => todo.title)
  },
})

Like this:

// custom useFetch
export function useAppFetch<ResT, DataT>(
  request: NitroFetchRequest,
  options: UseFetchOptions<ResT, DataT> = {}
) {
  const defaults: typeof options = {
    $fetch: useNuxtApp().$api,
  };

  const params = defu(options, defaults);

  return useFetch(request, params);
}


const { data: todos } = useAppFetch("/todos", {
  transform: (res: Todo[]) => {
    return res.map((todo) => todo.title)
  },
})

Doing this is wrong:

const { data: todos } = useFetch<Todo[]>("/todos", {
  transform: (res) => {
    return res.map((todo) => todo.title)
  },
})

Because you are saying that the data returned from useFetch is a Todo[], but that's not true, it's a string[].

@jxk-developer
Copy link
Author

With transform ResT is the input and DataT is the output, just type the parameter of transform's function and let it infer the output.

// normal useFetch
const { data: todos } = useFetch("/todos", {
  transform: (res: Todo[]) => {
    return res.map((todo) => todo.title)
  },
})

Like this:

// custom useFetch
export function useAppFetch<ResT, DataT>(
  request: NitroFetchRequest,
  options: UseFetchOptions<ResT, DataT> = {}
) {
  const defaults: typeof options = {
    $fetch: useNuxtApp().$api,
  };

  const params = defu(options, defaults);

  return useFetch(request, params);
}


const { data: todos } = useAppFetch("/todos", {
  transform: (res: Todo[]) => {
    return res.map((todo) => todo.title)
  },
})

Doing this is wrong:

const { data: todos } = useFetch<Todo[]>("/todos", {
  transform: (res) => {
    return res.map((todo) => todo.title)
  },
})

Because you are saying that the data returned from useFetch is a Todo[], but that's not true, it's a string[].

Thank you so much for the explanation. It works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants