I'm trying to make the response from an axios request type-safe, but am having problems making the TypeScript compiler infer the type correctly. Consider the following function which simply returns an axios request that returns the required data in a .then block and catches any error with a .catch block:
interface ServerResponse {
data: {
User_by_pk: User;
};
}
interface User {
id: string;
password: string;
}
function postRequest() {
return axios
.request<ServerResponse>({
method: 'POST',
url: 'http://example.com',
data: someData
})
.then((res) => {
return res.data.data.User_by_pk; //User type
})
.catch((error: AxiosError<ServerResponse>) => {
console.log(error.message);
return null;
});
}
I would have assumed this function would get the return type Promise<User | null> (The data returned in the .then is of type User), but instead, it gets the return type Promise<any>. Changing null to undefined gives the same result. I even tried explicitly stating the return type of the function, but when calling the function with for example let user = await postRequest(); the variable user gets the type User and not User | null as expected.
If I remove the .catch block the function's return type is correctly recognised as Promise<User>, but once I add the .catch it instead becomes Promise<any> instead of Promise<User | null>.
I did some googling and some people suggested using a library with a Maybe or Result type like True Myth, but it seems a bit overkill if this functionality is already built into TypeScript with Optionals and the? operator (Optional Chaining). How can I get TypeScript to give the correct return type of my function?