Closed rikbrown closed 1 year ago
The "union of all types" behaviour also seems to happen if I forgo makeEndpoint
but use satisfies
instead e.g.
export const getSubredditEndpoint = {
method: "get",
path: "r/:displayName/about",
response,
} as const satisfies ZodiosEndpointDefinition
And when using apiBuilder
and the spread operator like in this issue's reply's example: https://github.com/ecyrbe/zodios/issues/149#issuecomment-1255469067
So I think I'm probably doing something wrong but would love pointers.
Yes, two things here:
request
has definitly a bug where it incorrectly infers all responses into a union. So for now, just use aliases or get
, post
... shorcuts. You'll have better type inference if you use thoses. I higly recommend using aliases. it makes everything so less verbose.Here is a fixed version :
import { Zodios } from "@zodios/core";
import { makeEndpoint, makeParameters, makeApi } from "@zodios/core";
import { z } from "zod";
export const subredditSchema = z.object({
display_name: z.string(),
icon_img: z.optional(z.nullable(z.string())),
community_icon: z.optional(z.nullable(z.string()))
});
const subredditResponse = z.object({
data: subredditSchema
});
const getSubredditEndpoint = makeEndpoint({
method: "get",
alias: 'getSubreddit',
path: "r/:displayName/about",
response: subredditResponse
});
const postSchema = z.object({
permalink: z.string(),
name: z.string(),
title: z.string(),
subreddit: z.string(),
author: z.string(),
ups: z.number(),
likes: z.nullable(z.boolean()),
created: z.number().transform((n) => new Date(n * 1000)),
num_comments: z.number(),
post_hint: z.optional(z.string()),
url: z.optional(z.string()),
selftext: z.optional(z.string()),
preview: z.optional(
z.object({
images: z.array(
z.object({
resolutions: z.array(
z.object({
url: z.string(),
width: z.number(),
height: z.number()
})
)
})
)
})
)
});
const postResponse = z.object({
kind: z.literal("Listing"),
data: z.object({
after: z.nullable(z.string()),
before: z.nullable(z.string()),
children: z.array(
z.object({
kind: z.literal("t3"),
data: postSchema
})
)
})
});
export const listPostsEndpoint = makeEndpoint({
method: "get",
path: ":type",
alias: 'listPosts',
parameters: [
{
name: "after",
schema: z.optional(z.string()),
type: "Query"
},
{
name: "limit",
schema: z.optional(z.number()),
type: "Query"
},
{
name: "type",
type: "Path",
schema: z.enum(["hot", "best", "new", "top", "rising"])
}
],
response: postResponse
});
const subredditListResponse = z.object({
kind: z.literal("Listing"),
data: z.object({
after: z.nullable(z.string()),
before: z.nullable(z.string()),
children: z.array(
z.object({
kind: z.literal("t5"),
data: subredditSchema
})
)
})
});
export const listSubscribedSubredditsEndpoint = makeEndpoint({
method: "get",
path: "subreddits/mine/subscriber",
alias: 'listSubscribedSubreddits',
parameters: [
{
name: "after",
schema: z.optional(z.string()),
type: "Query"
},
{
name: "limit",
schema: z.optional(z.number()),
type: "Query"
}
],
response: subredditListResponse
});
export type SubredditListingResponse = z.infer<typeof subredditListResponse>;
const withMakeApi = new Zodios(
"https://oauth.reddit.com",
[listPostsEndpoint, getSubredditEndpoint, listSubscribedSubredditsEndpoint],
{
axiosConfig: {
headers: {
Authorization: "Bearer foo"
},
params: {
raw_json: 1
}
}
}
);
async function af() {
const rWithMakeApi = await withMakeApi.listSubscribedSubreddits({
queries: { limit: 100, after: "" }
});
}
So i'll rename this issue as a bug for request
returning a union
Much cleaner with aliases, thank you. I saw them mentioned in your doc but it wasn't clear exactly how to use them (didn't realise they turned into methods like that).
Thanks for the fast help. I am really enjoying using Zodios!
Thank you for sponsoring zodios.
i'll update the sponsors list. Very much appeciated. This helps a lot for keeping docs website running and renewed.
@rikbrown union response bug is now fixed on @zodios/core
v10.7.3
I am seeing some weird behaviour with typings, but I might be doing something stupid.
In short, I'm using
makeEndpoint
andmakeApi
to split my definitions up.However, the return type of
client.request
seems to be eithernever
(when usingmakeApi
) or a union of all of the possible response types (when not using it). Have a look at the sandbox below and hover over the variables to see the inferred return types.Sandbox: https://codesandbox.io/s/silent-lake-2yzxnl?file=/src/index.ts
The actual code works, it just seems to be typing.
Am I messing something up in my definitions or is something else awry?