Replies: 4 comments
-
After working on this some more I believe this typechecks, though it seems kinda verbose: const parsePaginatedHeaders = <
T extends z.ZodObject<
z.extendShape<typeof PaginatedList._shape, any>,
"strip" | "passthrough" | "strict", // HACK: UnknownKeysParam is not exported
z.ZodTypeAny,
any,
any
>
>(
zodModel: T
) => (elem: z.infer<T>, meta: FetchBaseQueryMeta | undefined) => {
const linkHeaderStr = meta?.response?.headers.get('Link')
if (linkHeaderStr != null) {
const parsedHeaders = parseLinkHeader(linkHeaderStr)
if (parsedHeaders != null) {
elem.links = {
next: parsedHeaders['next'],
prev: parsedHeaders['prev']
}
}
}
const parsed = zodModel.parse(elem)
return parsed
} Edit: ended up extracting this out into: export type ZodExtends<
A extends z.SomeZodObject,
B extends z.SomeZodObject
> = z.ZodObject<
z.extendShape<A['_shape'], B['_shape']>,
'strip' | 'passthrough' | 'strict', // HACK: UnknownKeysParam is not exported
z.ZodTypeAny,
any,
any
> |
Beta Was this translation helpful? Give feedback.
-
The proper use of generic types in zod is somehow unclear in document. I've managed to work it out as follows: // The zod model with generics type in function form
const PaginatedList = <T extends z.ZodTypeAny>(elemType: T) =>
z.object({
// some properties omitted
url: z.string(),
data: z.array(elemType),
});
// The "dynamic type" of model "PaginatedList"
// Which extends z.ZodTypeAny
// The generic param T here is dynamic type
// Note: require typescript@^4.7 for instantiation expressions
type PaginatedListModel<T extends z.ZodTypeAny> = ReturnType<typeof PaginatedList<T>>;
// The "static type" of model "PaginatedList"
// Which is like z.infer<z.ZodTypeAny>
// The generic param T here is static type
type PaginatedList<T> = z.infer<PaginatedListModel<z.ZodType<T>>>;
/*
= {
url: string;
data: T[];
}
*/
// The parser
const definePaginatedListParser =
<T extends z.ZodTypeAny>(zodModel: PaginatedListModel<T>) =>
(data: z.infer<typeof zodModel>): PaginatedList<T> => {
return zodModel.parse(data);
};
// Using verified data in codebase
const extractData = (list: PaginatedList<string>): string[] => {
return list.data;
}; |
Beta Was this translation helpful? Give feedback.
-
Not sure if this is what you look for (and I can find a better place to post this). export function PaginatedResponseSchema<T extends z.ZodType>(recordSchema: T) {
return z.object({
rowAmount: z.number().int().nonnegative(),
pageAmount: z.number().int().nonnegative(),
records: z.array(recordSchema),
});
}
export type PaginatedResponse<T> = z.infer<ReturnType<typeof PaginatedResponseSchema<z.ZodType<T>>>>;
const pageDto = await fetchHelper(`/api/mock/users/${userId}/forumposts?page=${currentPage}&pageSize=${postsPerPage}`, { method: 'GET' }, PaginatedResponseSchema(ForumpostSchema));
pageDto.records // has type from ForumpostSchema |
Beta Was this translation helpful? Give feedback.
-
just came across this issue while trying to look for a way to do exactly this, a function to create a "generic" paginated schema. I've run into a very odd issue with Intellisense in my IDE. Typescript seems to go beserk when I try and define: export function PaginatedResponseSchema<T extends z.ZodType>(recordSchema: T) {
return z.object({
data: z.array(recordSchema),
total: z.number(),
page: z.number(),
pageSize: z.number(),
});
} my IDE/tsserver immediately become unresponsive. Comment out that bit, back to normal. I really have no idea why -- I'm assuming it has to do something with the "internals" of |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hey folks. I've recently introduced zod into my codebase, and now I'm trying to implement something to help with validating some paginated input data. I looked through the existing issues and discussions but didn't come across anything that might help me work through this.
I have various payloads of this shape from different endpoints that return paginated lists:
Because the endpoint pagination data in the
Links
header, I wanted to incorporate it into the zod model to avoid having to plumb arbitrary header info through my application. I represented this in zod as:I'm trying to write a
transformResponse
function to inject the pagination info into the payload, and then parse it using the zod model. I was hoping to use generic types to work through this, but it's not quite working out.What I have so far:
This function itself typechecks, but the usage of the function
transformResponse: parsePaginatedHeaders(PaginatedListSomeDataType)
doesn't (the types of_shape
don't match up).I took a look through the type definitions and
ZodObject.extend
, and I believe I need to represent the merged types somehow. Thought I'd ask here first since the type definition are quite complex.Beta Was this translation helpful? Give feedback.
All reactions