Replies: 2 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.
0 replies
-
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.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
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