I have a function that uses an axios instance and has type async function register(data: RegisterData): Promise<AxiosResponse<UserResponse, any>>
export const register = (data: RegisterData) => api.post<UserResponse>('register', data)
Using the vue 3 composition api I am trying to create a wrapper over the form logic. The request
parameter accepts a register
function (or other similar functions).
form.ts
import {reactive, ref} from 'vue'
import Errors from '../helpers/Errors'
import type {AxiosResponse} from 'axios'
export function useForm<T extends Record<string, any>, R extends (...args: any) => Promise<AxiosResponse>>(init: T, request: R) {
const form = reactive<T>(init)
const errors = reactive(new Errors())
const isLoading = ref(false)
const makeRequest = () => {
isLoading.value = true
errors.clear()
return request(form)
.then(response => Promise.resolve(response))
.catch(e => {
if (e.response.status === 422) {
errors.save(e.response.data.errors)
}
return Promise.reject(e)
})
.finally(() => isLoading.value = false)
}
return {form, errors, isLoading, makeRequest}
}
RegisterPage.vue
import {useForm} from '../../../composables/form'
import {register} from '../../../api/auth'
// ...
const {form, isLoading, errors, makeRequest} = useForm({
username: null,
password: null,
password_confirmation: null,
referral_code: null
}, register)
makeRequest() // returns value of Promise<AxiosResponse<any, any>> type
// ...
But when I call the wrapper function, it returns the following type Promise<AxiosResponse<any, any>>
How can I make the makeRequest
function return the same type as the register
function (Promise<AxiosResponse<UserResponse, any>>
)?
CodePudding user response:
You can use a type assertion for the makeRequest
function.
export function useForm<
T extends Record<string, any>,
R extends (...args: any) => Promise<AxiosResponse>
>(init: T, request: R) {
/* ... */
const makeRequest = (() => {
/* ... */
}) as () => ReturnType<R>
/* ... */
}
Now the returned makeRequest
function will have the correct type.
const {form, isLoading, errors, makeRequest} = useForm({
username: null,
password: null,
password_confirmation: null,
referral_code: null
}, register)
const result = makeRequest()
// ^? const result: Promise<AxiosResponse<UserResponse, any>>