zod-express-middleware icon indicating copy to clipboard operation
zod-express-middleware copied to clipboard

Safer and better typings using z.output

Open gpichot opened this issue 1 year ago • 1 comments

Hello,

In my projects I need to improve the typings as is does not always conform to what we get.

For instance using the schema:

z.object({
   value: z.number().default(10),
})

The type will be { value?: number | undefined } while the output type is :{ value: number }

In my code, I therefore use:

import {
  processRequest as zodProcessRequest,
  processRequestBody as zodProcessRequestBody,
  processRequestQuery as zodProcessRequestQuery,
  processRequestParams as zodProcessRequestParams,
} from 'zod-express-middleware'

export function processRequestBody<Schema extends z.ZodSchema<unknown>>(
  schema: Schema
): express.RequestHandler<ParamsDictionary, unknown, z.output<Schema>, unknown> {
  return zodProcessRequestBody(schema)
}

export function processRequestQuery<Schema extends z.ZodSchema<unknown>>(
  schema: Schema
): express.RequestHandler<ParamsDictionary, unknown, unknown, z.output<Schema>> {
  return zodProcessRequestQuery(schema)
}

export function processRequestParams<Schema extends z.ZodSchema<unknown>>(
  schema: Schema
): express.RequestHandler<z.output<Schema>, unknown, unknown, unknown> {
  return zodProcessRequestParams(schema)
}

export function processRequest<
  TParams extends z.ZodSchema<unknown>,
  TQuery extends z.ZodSchema<unknown>,
  TBody extends z.ZodSchema<unknown>
>(
  schemas: {
    params?: TParams
    query?: TQuery
    body?: TBody
  }
): express.RequestHandler<z.output<TParams>, unknown, z.output<TBody>, z.output<TQuery>> {
  return zodProcessRequest(schemas)
}

Do you think it would be possible to update the types to improve the typings?

I can create a PR if needed.

Best, Gabriel

gpichot avatar Feb 16 '24 18:02 gpichot

In Zod v3.20 and above, the preferred way to get the output type of a schema is z.infer.

sidonaldson avatar May 29 '24 16:05 sidonaldson