我是新手,不会表达,但不会编程.我已经创建了一个验证中间件,它使用YUP来验证发送到服务器的正文

UserRoutes.ts

import validate from "@middlewares/ValidationMiddleware.ts";
import userSchema from "@schemas/models/用户架构.";

router.post("/signup", validate(userSchema), signupUser); #signupUser is the controller/service for logic

用户架构.

import * as Yup from "yup";

const userSchema = Yup.object({
  body: Yup.object().shape({
    password: Yup.string()
      .min(8, "Password must be at least 8 characters")
      .matches()... // there are 4 matches here. too much code if I add all
      .required(),
    confirmPassword: Yup.string()
      .min(8, "Password must be at least 8 characters")
      .matches()... // there are 4 matches here. too much code if I add all
      .oneOf([Yup.ref("password"), undefined], "Passwords must match")
      .required(),
  }),
});

export default userSchema;

ValidationMiddleware.ts

import { NextFunction, Request, Response } from "express";
import { AnySchema, ValidationError } from "yup";

const validate =
  (schema: AnySchema) =>
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      await schema.validate(
        {
          body: req.body,
          query: req.query,
          param: req.params,
        },
        {
          abortEarly: false, // get all errors on all fields
        }
      );

      next();
    } catch (e) {
      if (e instanceof ValidationError) {
        console.log(e.errors); // shows all errors as an array (no key)
        const validationErrors: any = {};
        e.inner.forEach((error) => {
          if (error.path) {
            validationErrors[error.path] = error.message;
          }
        });
        console.log(validationErrors); // displays errors as an object but value is only 1 of the errors
        return res.status(400).json(validationErrors);
      }
      return res.status(500).send("Internal Server Error");
    }
  };

export default validate;

输出

  // e.errors
  [
   'Password must have 1 lowercase character',
   'Password must have 1 digit character',
   'Password must have 1 uppercase character',
   'Password must be at least 8 characters',
   'body.password is a required field',
   'Password must have 1 lowercase character',
   'Password must have 1 digit character',
   'Password must have 1 uppercase character',
   'Password must be at least 8 characters',
   'body.confirmPassword is a required field'
 ]

 // validationErrors
 {
   'body.password': 'body.password is a required field',
   'body.confirmPassword': 'body.confirmPassword is a required field'
 }

正如你在我的代码和输出中所看到的,e.errors有我想要返回的所有验证错误,但它是作为数组返回的,所以我不知道应该在哪个字段中添加它们,而在validationErrors中,它是作为对象返回的,但每个字段只有一个错误.

我应该如何继续呢?

推荐答案

我想我找到答案了.

if (error.path) {
   validationErrors[error.path] = error.message;
}

error.path有多个error.message 所以应该是这样的

if (error.path) {
  if (!validationErrors[error.path]) {
    validationErrors[error.path] = []; // Initialize array message
  }
  validationErrors[error.path].push(error.message); // push message to array
}

Typescript相关问答推荐

如何正确修复TypScript 4.7到4.8升级中的TS 2345编译错误

React router 6.22.3不只是在生产模式下显示,为什么?

为什么tsx不判断名称中有"—"的属性?'

对扩展某种类型的属性子集进行操作的函数

仅针对某些状态代码重试HTTP请求

为什么T[数字]不也返回UNDEFINED?

如何判断对象是否有重叠的叶子并产生有用的错误消息

表单嵌套太深

TypeScrip省略了类型参数,仅当传递另一个前面的类型参数时才采用默认类型

Angular文件上传到Spring Boot失败,多部分边界拒绝

如何创建一家Reduxstore ?

如何过滤文字中的类对象联合类型?

RXJS将对键盘/鼠标点击组合做出react

如何在不违反挂钩规则的情况下动态更改显示内容(带有状态)?

Rxjs将省略的可观测对象合并到一个数组中

编剧- Select 动态下拉选项

显式推断对象为只读

在类型{}上找不到带有string类型参数的索引签名 - TypeScript

基于可选参数的动态类型泛型类型

如何从 Select 元素中删除选项