Trouble with telling typescript the return type of fetch when using @sapphire/result

Hi there, I have a function that fetches an API using the native fetch function. The fetch is wrapped in Result.fromAsync(), and I wanted to do Result.fromAsync<Promise<APIResponse>> since I know what the API will return. The problem is, when doing Result.fromAsync<Promise<APIResponse>> Typescript says that Response is missing certain properties that I know the API will return. How would I tell Typescript I know that the fetch will return this?
Result.fromAsync<Promise<OMGLOLAPIResponse>>(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Argument of type 'Promise<Response>' is not assignable to parameter of type 'Awaitable<Resolvable<Promise<OMGLOLAPIResponse>, unknown>> | (() => Awaitable<Resolvable<Promise<OMGLOLAPIResponse>, unknown>>)'.
Type 'Promise<Response>' is not assignable to type 'Promise<OMGLOLAPIResponse>'.
Type 'Response' is missing the following properties from type 'OMGLOLAPIResponse': request, response ts(2345)

fetch(`${OMGLOL_API_URL}/address/${ADDRESS}/purl`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.OMGLOL_API_KEY}`
},
body: JSON.stringify({
name: path,
url: destination,
listed: true
})
})
)
Result.fromAsync<Promise<OMGLOLAPIResponse>>(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Argument of type 'Promise<Response>' is not assignable to parameter of type 'Awaitable<Resolvable<Promise<OMGLOLAPIResponse>, unknown>> | (() => Awaitable<Resolvable<Promise<OMGLOLAPIResponse>, unknown>>)'.
Type 'Promise<Response>' is not assignable to type 'Promise<OMGLOLAPIResponse>'.
Type 'Response' is missing the following properties from type 'OMGLOLAPIResponse': request, response ts(2345)

fetch(`${OMGLOL_API_URL}/address/${ADDRESS}/purl`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.OMGLOL_API_KEY}`
},
body: JSON.stringify({
name: path,
url: destination,
listed: true
})
})
)
6 Replies
net-tech-
net-tech-12mo ago
Should I have put this in #Coding since it's more TS related and not sapphire related
Lioness100
Lioness10012mo ago
@nettech try this:
await Result.fromAsync<OMGLOLAPIResponse>(async () => {
const res = await fetch(`${OMGLOL_API_URL}/address/${ADDRESS}/purl`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.OMGLOL_API_KEY}`
},
body: JSON.stringify({
name: path,
url: destination,
listed: true
})
});

return res.json();
});
await Result.fromAsync<OMGLOLAPIResponse>(async () => {
const res = await fetch(`${OMGLOL_API_URL}/address/${ADDRESS}/purl`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.OMGLOL_API_KEY}`
},
body: JSON.stringify({
name: path,
url: destination,
listed: true
})
});

return res.json();
});
Assuming fetch is whatwg-spec compliant
net-tech-
net-tech-12mo ago
yep that works my original solution did a straight return because i wanted to avoid defining variables that i was gonna use immediately
Lioness100
Lioness10012mo ago
The problem is you have to send the request and parse it as json. Both are two different promises, and both can reject, but I assumed you wanted to handle them as one. So it would need to be in a callback. Also, you have a few type confusions
net-tech-
net-tech-12mo ago
oh, which ones? also thanks for the quick reply
Lioness100
Lioness10012mo ago
The most important one is, as I said, fetch doesn't return json. Also, the value in the generics should not be a promise, it should be the resolved value.