Skip to content

Instantly share code, notes, and snippets.

@Tanimodori
Created June 15, 2022 02:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tanimodori/70a7025d4199a36895d22fe7fea52dd4 to your computer and use it in GitHub Desktop.
Save Tanimodori/70a7025d4199a36895d22fe7fea52dd4 to your computer and use it in GitHub Desktop.
How to use generic types in Zod
import { z } from 'zod';
// 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;
};
@Tanimodori
Copy link
Author

Original code from colinhacks/zod#670

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment