Skip to content

Instantly share code, notes, and snippets.

@davidparys
Created June 8, 2025 19:14
Show Gist options
  • Save davidparys/08c31c0da8eb56b785266ad63cbd653d to your computer and use it in GitHub Desktop.
Save davidparys/08c31c0da8eb56b785266ad63cbd653d to your computer and use it in GitHub Desktop.
// composables/ApiResponse.ts
/*
Usage:
const message = apiRef({
route: '/api/hello-world',
method: 'get',
defaultValue: null
})
const getTheData = async () => {
const response = await $fetch('/api/hello-world')
message.value = response
}
*/
import type { InternalApi } from 'nitropack'
export type ApiRoutes = keyof InternalApi
export type ApiResponse<T extends ApiRoutes, M extends keyof InternalApi[T]> = InternalApi[T][M]
export const apiRef = <T extends ApiRoutes, M extends keyof InternalApi[T], D>(opts: {
route: T
method: M
defaultValue: D
}) => ref<ApiResponse<T, M> | D>(opts.defaultValue)
import type { UseFetchOptions } from 'nuxt/app'
import type { InternalApi } from 'nitropack'
export const useTypedFetch = <T extends ApiRoutes, M extends keyof InternalApi[T]>(
route: T,
method: M,
opts?: Omit<UseFetchOptions<ApiResponse<T, M>>, 'method'>,
) => {
return useFetch(route, {
...opts,
method: method as any, // Type assertion needed due to Nuxt's type constraints
transform: response => response as ApiResponse<T, M>,
})
}
// USAGE:
// const message = apiRef({
// route: '/api/hello-world',
// method: 'get',
// defaultValue: null
// })
// const getTheData = async () => {
// const response = await $fetch('/api/hello-world')
// message.value = response
// }
/**
* Type utility to infer response type from API route and method
*/
export type ApiTypedRoute<
T extends ApiRoutes,
M extends keyof InternalApi[T],
> = ApiResponse<T, M>
// USAGE :
// / Example usage:
// const fetchSomething = async (): Promise<ApiTypedRoute<'/api/hello-world', 'get'>> => {
// return await $fetch('/api/hello-world')
// }
// // Or type a variable:
// const myData: ApiTypedRoute<'/api/hello-world', 'get'> = someResponse
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment