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
Generic response type not working with useFetch
#15401
Comments
Temporary workaround: const customApi = async <T>() => {
const asyncData = await useFetch<T>('https://api.nuxtjs.dev/mountains', {
// @ts-expect-error: https://github.com/nuxt/nuxt.js/issues/15401
pick: ['title'],
method: 'GET',
}) as any; // eslint-disable-line @typescript-eslint/no-explicit-any
return asyncData;
};
const result = await customApi<{ title: string }>();
console.log(result.data.value?.title); |
I'm afraid this is correct TS behaviour and not a bug. You need to specify that const customApi = async <T extends { title: any }>() => {
const asyncData = await useFetch<T>('https://api.nuxtjs.dev/mountains', {
pick: ['title'],
method: 'GET'
})
return asyncData
}
const result = await customApi<{ title: string }>()
console.log(result.data.value?.title) You can set |
@danielroe I set now 'strict' to 'false', reload editor and still have the same problem: |
You're right; it seems it wasn't caused by enabling strict mode. The correct solution, from a TypeScript point of view, is the code I provided above. |
I find it hard to believe because it is a bit contradictory to the idea of using generics. Especially since I was able to define every type successfully before. It turns out that from now on, every response from api must be |
No; it's still fully typed. Your custom composable just needs to specify that any valid type must have a title field, because we're going to pick the title field. Note that the |
The problem is that composable similar to const customApi = async <T>(request: NitroFetchRequest, options: UseFetchOptions<T extends void ? unknown : T, (res: T extends void ? unknown : T) => T extends void ? unknown : T, KeyOfRes<(res: T extends void ? unknown : T) => T extends void ? unknown : T>>) => {
const statusCode = ref<number>(200);
const asyncData = await useFetch<T>(request, {
initialCache: false,
baseURL: <url>,
headers: { ...headers, authorization: localStorage['auth-token'] }, // current localStorage
onResponseError: async (ctx) => {
statusCode.value = ctx.response.status;
await onResponseError(ctx);
},
onRequest,
parseResponse,
...options,
});
return { ...asyncData, statusCode };
}; As you can see, I can't extends T here, because wherever I try to use this composable it will be a different type. Is there any other way for |
In that case, you can copy the types from The other alternative is to simply override them, e.g.: const customApi = async <T>(request: NitroFetchRequest, options: UseFetchOptions<T extends void ? unknown : T, (res: T extends void ? unknown : T) => T extends void ? unknown : T, KeyOfRes<(res: T extends void ? unknown : T) => T extends void ? unknown : T>>) => {
const statusCode = ref<number>(200);
const asyncData = await useFetch(request, {
initialCache: false,
baseURL: <url>,
headers: { ...headers, authorization: localStorage['auth-token'] }, // current localStorage
onResponseError: async (ctx) => {
statusCode.value = ctx.response.status;
await onResponseError(ctx);
},
onRequest,
parseResponse,
...options,
}) as AsyncData<T, FetchError | null>;
return { ...asyncData, statusCode };
}; |
@danielroe At first glance, it seems to work. I don't know how to thank you, you are amazing! ❤️ |
You are very welcome 😊 |
@danielroe Sorry to bother you again, but I have encountered one irregularity. Nuxt RC13 decided to share the original error (nuxt/framework#8521) which I'm very happy about. Unfortunately, |
Yes, the error type is the second generic - |
Yes, I know. I mean a ready type with missing fields returned by AsyncData<T, (FetchError<ApiError> & { status: number }) | null> I'm not bothered anymore, thank you for your time and help. |
Versions
Reproduction
https://stackblitz.com/edit/github-itsfns?file=app.vue
Works fine (
asyncData
is a_AsyncData<{ title: string }, true | FetchError<any> | null>
:Not working (
asyncData
is a_AsyncData<PickFrom<_ResT, KeyOfRes<Transform>>, true | FetchError<any> | null>
):Additionally, setting the `pick1 field causes an error.
Additional Details
I would like to add that everything worked very well before. Unfortunately, now even undoing the Nuxt version doesn't help.
Steps to reproduce
Copy and paste code above.
What is Expected?
I want to create a custom
useFetch
and be able to type a response (link1, link2)What is actually happening?
I am getting a weird type causing my application to fail.
The text was updated successfully, but these errors were encountered: