RTK Query типизация axiosBaseQuery
Есть такой базовый запрос:
export const axiosBaseQuery = ({baseUrl = '', headers}: IAxiosBaseQuery): BaseQueryFn<IBaseQuery, unknown, unknown> => {
return async ({url, params, method, data}) => {
try {
const result = await axios({
url: baseUrl + url,
method: method,
...(params && {params: params}),
...(headers && {headers: headers({})}),
...(data && {data: data}),
responseType: 'json'
});
return {
data: result.data
};
} catch (axiosError) {
const err = axiosError as AxiosError;
return {
error: {status: err.response?.status, data: err.response?.data}
};
}
};
};
и есть объявление (пародия) на интерсепторы:
export const APIBaseQueryInterceptor = axiosBaseQuery({
baseUrl: 'https://jsonplaceholder.typicode.com',
headers: (headers) => {
const token = 'test';
if (token) {
headers['authorization'] = `Bearer ${token}`;
}
return headers;
}
});
export const APIBaseQuery: BaseQueryFn<IBaseQuery, unknown, unknown> = async (args, api, extraOptions) => {
const result = await APIBaseQueryInterceptor(args, api, extraOptions);
if (result.error && result.error.status === 404) {
// try to get a new token
//const refreshResult = await APIBaseQueryInterceptor('/refreshToken', api, extraOptions);
console.log('test');
if (false) {
// store the new token
//api.dispatch(tokenReceived(refreshResult.data));
// retry the initial query
//result = await APIBaseQueryInterceptor(args, api, extraOptions);
} else {
//api.dispatch(loggedOut());
}
}
return result;
};
и в APIBaseQuery когда я проверяю на ошибку, result.error.status === 404, он мне выдает на result.error:
TS2571: Object is of type 'unknown'.
когда я вызываю генерик, таким образом: BaseQueryFn<IBaseQuery, unknown, FetchBaseQueryError>, ошибка пропадает... но начинает ругатся на return async ({url, params, method, data})... в axiosBaseQuery со следующим текстом:
TS2322: Type '({ url, params, method, data }: IBaseQuery) => Promise<{ data: any; error?: undefined; } | { error: { status: number | undefined; data: any; }; data?: undefined; }>' is not assignable to type 'BaseQueryFn<IBaseQuery, unknown, FetchBaseQueryError, {}, {}>'. Type 'Promise<{ data: any; error?: undefined; } | { error: { status: number | undefined; data: any; }; data?: undefined; }>' is not assignable to type 'MaybePromise<QueryReturnValue<unknown, FetchBaseQueryError, {}>>'. Type 'Promise<{ data: any; error?: undefined; } | { error: { status: number | undefined; data: any; }; data?: undefined; }>' is not assignable to type 'PromiseLike<QueryReturnValue<unknown, FetchBaseQueryError, {}>>'. Types of property 'then' are incompatible. Type '<TResult1 = { data: any; error?: undefined; } | { error: { status: number | undefined; data: any; }; data?: undefined; }, TResult2 = never>(onfulfilled?: ((value: { data: any; error?: undefined; } | { error: { status: number | undefined; data: any; }; data?: undefined; }) => TResult1 | PromiseLike<...>) | null | und...' is not assignable to type '<TResult1 = QueryReturnValue<unknown, FetchBaseQueryError, {}>, TResult2 = never>(onfulfilled?: ((value: QueryReturnValue<unknown, FetchBaseQueryError, {}>) => TResult1 | PromiseLike<...>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | ... 1 more ... | undefined) => PromiseLike<...>'. Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. Types of parameters 'value' and 'value' are incompatible. Type '{ data: any; error?: undefined; } | { error: { status: number | undefined; data: any; }; data?: undefined; }' is not assignable to type 'QueryReturnValue<unknown, FetchBaseQueryError, {}>'. Type '{ error: { status: number | undefined; data: any; }; data?: undefined; }' is not assignable to type 'QueryReturnValue<unknown, FetchBaseQueryError, {}>'. Type '{ error: { status: number | undefined; data: any; }; data?: undefined; }' is not assignable to type '{ error?: undefined; data: unknown; meta?: {} | undefined; }'. Types of property 'error' are incompatible. Type '{ status: number | undefined; data: any; }' is not assignable to type 'undefined'.
Вроде все по документации сделал, но не могу понять где я что то упускаю...
Ответы (1 шт):
Автор решения: Dmitry Egorov
→ Ссылка
Попробуй так:
interface BaseError {
code: string | number;
message: string;
details: string[];
}
export const axiosBaseQuery = ( { baseUrl }: { baseUrl: string } = { baseUrl: '' } ): BaseQueryFn<{
url: string
method: Method
data?: AxiosRequestConfig['data']
params?: AxiosRequestConfig['params']
},
unknown,
BaseError> =>
async ( { url, method, data, params } ) => {
try {
const result = await axios( { url: baseUrl + url, method, data, params } )
return { data: result.data }
} catch ( axiosError: any ) {
let err = axiosError as AxiosError<BaseError>
const error: BaseError = {
code: err.response?.data?.code || err.response?.status || '',
message: err.response?.data?.message || err?.message || 'Неизвестная ошибка',
details: err.response?.data?.details || []
}
return { error }
}
}