DEV Community

Justin Poehnelt
Justin Poehnelt

Posted on • Originally published at justin.poehnelt.com on

Strongly Typed Yup Schema in TypeScript

This weekend I have been exploring conditional types in TypeScript to use with Firestore. These take the basic form of T extends U ? X : Y and are used to create a new type based on the type of T. I was curious if I could use this to create a strongly typed Yup schema.

The basic idea is to create a generic function that takes a Yup schema and a type. The function will return a Yup schema that is strongly typed to the type. The function will use a conditional type to determine the type of the schema and return the appropriate schema.

import * as yup from "yup"; export type ConditionalSchema<T> = T extends string ? yup.StringSchema : T extends number ? yup.NumberSchema : T extends boolean ? yup.BooleanSchema : T extends Record<any, any> ? yup.AnyObjectSchema : T extends Array<any> ? yup.ArraySchema<any, any> : yup.AnySchema; export type Shape<Fields> = { [Key in keyof Fields]: ConditionalSchema<Fields[Key]>; }; 
Enter fullscreen mode Exit fullscreen mode

With those two generic types, we can create a strongly typed Yup schema. These can obviously be extended to include more types and better handle arrays and objects.

Some example usage that keeps the TypeScript compiler happy:

interface Foo { stringField: string; booleanField: boolean; } yup.object<Shape<Foo>>({ stringField: yup.string().default(""), booleanField: yup.boolean().default(false), }); 
Enter fullscreen mode Exit fullscreen mode

And it works! 🎉

Top comments (0)