PROBLEM
Given a function returning a Promise
,
const fetchSomething = async (): Promise<DocumentType | ServerErrorType> => {
const data = await fetch(`/data`, {
method: "get",
headers: { "Content-Type": "application/json" },
});
try {
const res = await data.json();
return Promise.resolve(res);
} catch (err) {
return Promise.reject(err);
}
};
Called as such,
// TS evaluates both res and err as 'DocumentType | ServerErrorType'
fetchSomething()
.then((res) => console.log(res))
.catch((err) => console.log(err))
How can it be asserted and called in a way that if the Promise resolves, the result will be asserted as a DocumentType
, while if it rejects, then it asserts the result as a ServerErrorType
?
ALTERNATIVE SOLUTION
Quick and easy solution, is to assert the value directly when calling the function, as followed:
// TS evaluates res as 'DocumentType' and err as 'ServerErrorType'
fetchSomething()
.then((res as DocumentType) => console.log(res))
.catch((err as ServerErrorType) => console.log(err))
The problem in asserting as such, is I would end up asserting the results of the function anywhere I call it.
WHAT I TRIED
I tried asserting the values on fetchSomething
this way:
try {
const res = await data.json();
return Promise.resolve(res as DocumentType);
} catch (err) {
return Promise.reject(err as ServerErrorType);
}
But that doesn't seem to help TS evaluating the correct type.
CONCLUSIONS
Is there a clean way of asserting the returned values directly inside that function, based on the Promise result (either resolved or rejected)?
Type annotations on catch variable is currently not supported in Typescript. See here.
BTW I do recommend changes suggested by @T.J.Crowder