Search code examples
typescriptzod

How to use parameter as type definition?


Is it possible to dynamically define a parameter type based on another parameter?

Like in the following scenario:

import z from 'zod'

// I have a function that defines a command factory with a build function
const defineCommand = (name:string, schema: z.ZodTypeAny) => {
    return {
        schema,
        build: (payload: z.infer<typeof schema>) => {
            return {
                payload
            }
        }
    }
}

const CreatePostCommand = defineCommand('CreatePostCommand', z.object({
    title: z.string().min(2),
    body: z.string().min(2)
}));

// now when I call the build function there is no type check for the payload
const commandInstance = CreatePostCommand.build({foo: "bar"}) // <<-- this should cause type error

I know that it works with generics but this way I would have to pass in the "schema" twice. Once as type and once as schema object.


Solution

  • With generics, there is no need to pass it twice. Check it out:

    const defineCommand = <T extends z.ZodType>(name:string, schema: T) => {
        return {
            schema,
            build: (payload: z.infer<T>) => {
                return {
                    payload
                }
            }
        }
    }