node.js - Modalitatea corectă de a tipiza cererile primite cu Typescript și Express


Validez cererile primite cu zod și de asemenea îmi generez tipurile pentru corpoare etc. etc. folosind funcționalitatea infer.

Acum întrebarea mea este, cum să specific cel mai bine aceste tipuri în controllerul meu Express?

Să spunem că punctul meu final are nevoie de această structură a corpului:

{
  "name": string,
  "address": string
}

Am creat un tip din schema mea zod, să-l numim UserRequestBody. Acum, evident, aș dori să folosesc acest tip pentru a tipa cererea care sosește în controller. Am reușit să fac să funcționeze folosind interfața RequestHandler din Express, astfel:

const newUser: RequestHandler<unknown, unknown, UserRequestBody, unknown> = async (req, res, next) => {
  // here, I can now access the properties directly from the req.body
  console.log(req.body.name)
}

Este drăguț cu IntelliSense și toate cele, dar mă întreb dacă acesta este modul corect de a face asta? Mă întreb cum ar aborda și alți oameni acest lucru. Există o altă modalitate, mai inteligentă, de a scrie cererea?

Mulțumesc!

Răspuns #1

Poți folosi pachetul zod-express-middleware.

Middleware pentru express care folosește zod pentru a face cererile sigure din punct de vedere al tipului.

Se pare că ai furnizat doar tipul UserRequestBody pentru a trece verificarea tipului TSC. Dar nu există nicio validare.

De exemplu

import express from 'express';
import { validateRequest } from 'zod-express-middleware';
import { z } from 'zod';

const app = express();

// app is an express app
app.get(
  '/',
  validateRequest({
    body: z.object({
      name: z.string(),
      address: z.string(),
    }),
  }),
  (req, res) => {
    // req.body is now strictly-typed and confirms to the zod schema above.
    // req.body has type { name: string; address: string; };
    return res.json({ message: 'Validation for body passed' });
  },
);

package.json:

"zod": "^3.21.4",
"zod-express-middleware": "^1.4.0",
"@types/express": "^4.17.17",
"express": "^4.18.2",