class-validator:
文档翻译采用coze翻译:www.coze.com/store/bot/7… 有兴趣可以点击连接使用一下,需要梯子
class-validator 是一个强大而灵活的库,用于对 TypeScript 和 JavaScript 的类实例属性进行类型安全的验证。它基于装饰器提供了一种声明式的方式来装饰类属性,并对它们应用各种验证规则。内部使用了另一个名为 validator.js 的库来执行实际的验证逻辑。它广泛应用于 TypeScript 项目中,尤其是在使用像 NestJS 这样的框架时。
这个库的特点包括:
- 类型安全的验证:利用 TypeScript 的类型系统,可以确保验证规则与属性的类型相匹配,减少运行时错误。
- 装饰器支持:通过简单的装饰器,像
@IsString或@IsNotEmpty,你可以指定一个属性应该满足的验证要求。 - 自定义验证器:除了预设的验证装饰器,
class-validator允许创建自定义的验证函数来处理更复杂的验证逻辑。 - 简单的错误处理:如果对象验证失败,库可以返回一个包含错误详情的数组,方便开发者处理并响应用户输入错误。
- 分组验证:允许你定义多个分组来执行不同上下文中的验证规则集合,例如在创建时和更新时有不同的验证规则。
- 异步验证:部分验证器或自定义的验证函数可以是异步的,允许在验证过程中执行数据库查询等异步操作。
class-validator 非常适合于需要在后端进行严格数据验证的应用程序,也非常适合与类风格的 API 结合使用,是现代 web 应用开发的重要工具之一。
安装
npm install class-validator --save
注意:使用
class-validator时,请至少使用 npm@6。从 npm@6 开始,依赖树是扁平化的,这对于class-validator的正常运行是必需的。
使用方法
创建 类 并在你想验证的属性上添加一些 验证装饰器:
import {
validate,
validateOrReject,
Contains,
IsInt,
Length,
IsEmail,
IsFQDN,
IsDate,
Min,
Max,
} from 'class-validator';
export class Post {
@Length(10, 20)
title: string;
@Contains('hello')
text: string;
@IsInt()
@Min(0)
@Max(10)
rating: number;
@IsEmail()
email: string;
@IsFQDN()
site: string;
@IsDate()
createDate: Date;
}
let post = new Post();
post.title = 'Hello'; // 应该不通过验证
post.text = '这是一篇关于 hello world 的棒文章'; // 应该不通过验证
post.rating = 11; // 应该不通过验证
post.email = 'google.com'; // 应该不通过验证
post.site = 'googlecom'; // 应该不通过验证
validate(post).then(errors => {
// errors 是一个包含验证错误的数组
if (errors.length > 0) {
console.log('验证失败。错误:', errors);
} else {
console.log('验证成功');
}
});
validateOrReject(post).catch(errors => {
console.log('Promise 被拒绝(验证失败)。错误:', errors);
});
// 或者
async function validateOrRejectExample(input) {
try {
await validateOrReject(input);
} catch (errors) {
console.log('捕获到 promise 拒绝(验证失败)。错误:', errors);
}
}
传递选项
validate 函数可选地接受一个 ValidatorOptions 对象作为第二个参数:
export interface ValidatorOptions {
skipMissingProperties?: boolean;
whitelist?: boolean;
forbidNonWhitelisted?: boolean;
groups?: string[];
dismissDefaultMessages?: boolean;
validationError?: {
target?: boolean;
value?: boolean;
};
forbidUnknownValues?: boolean;
stopAtFirstError?: boolean;
}
重要 默认情况下
forbidUnknownValues的值被设置为true,强烈建议保持默认设置。 将其设置为false将导致未知对象通过验证!
错误验证
validate 方法返回一个 ValidationError 对象数组。每个 ValidationError 为:
{
target: Object; // 被验证的对象。
property: string; // 未通过验证的对象属性。
value: any; // 未通过验证的值。
constraints?: { // 失败的约束及其错误消息。
[type: string]: string;
};
children?: ValidationError[]; // 包含属性的所有嵌套验证错误
}
在我们的例子中,当我们验证 Post 对象时,我们有这样一个 ValidationError 对象数组:
[{
target: /* post object */,
property: "title",
value: "Hello",
constraints: {
length: "$property 必须长于或等于 10 个字符"
}
}, {
target: /* post object */,
property: "text",
value: "this is a great post about hell world",
constraints: {
contains: "text 必须包含 hello 字符串"
}
},
// 和其他错误
]
如果你不想在验证错误中暴露 target,在使用验证器时有一个特殊的选项:
validator.validate(post, { validationError: { target: false } });
这在通过 http 发送错误时尤其有用,你很可能不想暴露整个目标对象。
验证消息
你可以在装饰器选项中指定验证消息,如果该字段的验证失败,则该消息将在 ValidationError 中返回。
import { MinLength, MaxLength } from 'class-validator';
export class Post {
@MinLength(10, {
message: '标题太短',
})
@MaxLength(50, {
message: '标题太长',
})
title: string;
}
你可以在消息中使用几个特殊的代号:
$value- 正在验证的值$property- 正在验证的对象属性的名称$target- 正在验证的对象类的名称$constraint1,$constraint2, ...$constraintN- 由特定验证类型定义的约束
用法示例:
import { MinLength, MaxLength } from 'class-validator';
export class Post {
@MinLength(10, {
// 这里,$constraint1 会被替换为 "10",而 $value 会被替换为实际提供的值
message: '标题太短。最小长度是 $constraint1 个字符,但实际是 $value',
})
@MaxLength(50, {
// 这里,$constraint1 会被替换为 "50",而 $value 会被替换为实际提供的值
message: '标题太长。最大长度是 $constraint1 个字符,但实际是 $value',
})
title: string;
}
你也可以提供一个返回消息的函数。这允许你创建更细致的消息:
import { MinLength, MaxLength, ValidationArguments } from 'class-validator';
export class Post {
@MinLength(10, {
message: (args: ValidationArguments) => {
if (args.value.length === 1) {
return '太短,最小长度是 1 个字符';
} else {
return '太短,最小长度是 ' + args.constraints[0] + ' 个字符';
}
},
})
title: string;
}
消息函数接受 ValidationArguments,其中包含以下信息:
value- 正在验证的值constraints- 特定验证类型定义的约束数组targetName- 正在验证的对象类的名称object- 正在验证的对象property- 正在验证的对象属性的名称
数组验证
如果你的属性是一个数组,并且你想对数组中的每个项执行验证,你必须指定一个特殊的装饰器选项 each: true:
typescript
import { MaxLength } from 'class-validator';
export class Post {
@MaxLength(20, {
each: true,
})
tags: string[];
}
这将会验证 post.tags 数组中的每一项。
Set验证
如果你的属性是一个集合,并且你想对集合中的每个项执行验证,你必须指定一个特殊的装饰器选项 each: true:
import { MaxLength } from 'class-validator';
export class Post {
@MaxLength(20, {
each: true,
})
tags: Set<string>;
}
这将会验证 post.tags 集合中的每一项。
Map验证
如果你的属性是一个映射,并且你想对映射中的每个项执行验证,你必须指定一个特殊的装饰器选项 each: true:
import { MaxLength } from 'class-validator';
export class Post {
@MaxLength(20, {
each: true,
})
tags: Map<string, string>;
}
这将会验证 post.tags 映射中的每一项。
验证嵌套对象
如果你的对象包含嵌套对象,并且你希望验证器也执行它们的验证,那么你需要使用 @ValidateNested() 装饰器:
import { ValidateNested } from 'class-validator';
export class Post {
@ValidateNested()
user: User;
}
请注意,嵌套对象 必须 是一个类的实例,否则 @ValidateNested 不会知道哪个类是验证的目标。还要检查 验证普通对象。
它也适用于多维数组,例如:
import { ValidateNested } from 'class-validator';
export class Plan2D {
@ValidateNested()
matrix: Point[][];
}
验证 Promise
如果你的对象包含一个返回 Promise 值的属性,并且需要对其进行验证,则需要使用 @ValidatePromise() 装饰器:
import { ValidatePromise, Min } from 'class-validator';
export class Post {
@Min(0)
@ValidatePromise()
userId: Promise<number>;
}
它也可以很好地与 @ValidateNested 装饰器一起使用:
import { ValidateNested, ValidatePromise } from 'class-validator';
export class Post {
@ValidateNested()
@ValidatePromise()
user: Promise<User>;
}
extends继承验证装饰器
当你定义一个子类并且从另一个类继承时,子类将自动继承父类的装饰器。如果在后代类中重新定义了一个属性,那么装饰器将同时应用于其自己的类和基类。
import { validate } from 'class-validator';
class BaseContent {
@IsEmail()
email: string;
@IsString()
password: string;
}
class User extends BaseContent {
@MinLength(10)
@MaxLength(20)
name: string;
@Contains('hello')
welcome: string;
@MinLength(20)
password: string;
}
let user = new User();
user.email = 'invalid email'; // 继承的属性
user.password = 'too short'; // 密码不仅会针对 IsString 进行验证,还会针对 MinLength 进行验证
user.name = 'not valid';
user.welcome = 'helo';
validate(user).then(errors => {
// ...
}); // 它将返回 email、password、name 和 welcome 属性的错误
条件验证
条件验证装饰器(@ValidateIf)可以用来在提供的条件函数返回 false 时忽略属性上的验证器。条件函数接收被验证的对象,并且必须返回一个 boolean 值。
typescript
import { ValidateIf, IsNotEmpty } from 'class-validator';
export class Post {
otherProperty: string;
@ValidateIf(o => o.otherProperty === 'value')
@IsNotEmpty()
example: string;
}
在上面的例子中,除非对象的 otherProperty 是 "value",否则应用于 example 的验证规则不会运行。
注意,当条件为假时,所有验证装饰器都将被忽略,包括 isDefined。
白名单
即使你的对象是一个验证类的实例,它也可以包含未定义的其他属性。如果你不希望在对象上有这样的属性,请在 validate 方法中传递一个特殊的标志:
import { validate } from 'class-validator';
// ...
validate(post, { whitelist: true });
这将去除所有没有任何装饰器的属性。如果其他的装饰器不适用于你的属性,你可以使用 @Allow 装饰器:
import {validate, Allow, Min} from "class-validator";
export class Post {
@Allow()
title: string;
@Min(0)
views: number;
nonWhitelistedProperty: number;
}
let post = new Post();
post.title = 'Hello world!';
post.views = 420;
post.nonWhitelistedProperty = 69;
(post as any).anotherNonWhitelistedProperty = "something";
validate(post).then(errors => {
// post.nonWhitelistedProperty 没有定义
// (post as any).anotherNonWhitelistedProperty 没有定义
...
});
如果你更希望在存在任何非白名单属性时抛出错误,请在 validate 方法中传递另一个标志:
import { validate } from 'class-validator';
// ...
validate(post, { whitelist: true, forbidNonWhitelisted: true });
向装饰器传递上下文
可以向装饰器传递一个自定义对象,如果属性验证失败,将可以在 ValidationError 实例中访问。
import { validate } from 'class-validator';
class MyClass {
@MinLength(32, {
message: 'EIC编码至少需要32个字符',
context: {
errorCode: 1003,
developerNote: '被验证的字符串必须包含32个或更多字符。',
},
})
eicCode: string;
}
const model = new MyClass();
validate(model).then(errors => {
// errors[0].contexts['minLength'].errorCode === 1003
});
跳过缺失的属性
有时候你可能想跳过验证不存在于验证对象中的属性。当你只想更新对象的某些部分,并且只想验证已更新的部分,但跳过其他所有内容时,这通常是可取的,例如跳过缺失的属性。在这种情况下,你需要向 validate 方法传递一个特殊的标志:
import { validate } from 'class-validator';
// ...
validate(post, { skipMissingProperties: true });
当跳过缺失的属性时,有时候你可能不想跳过所有缺失的属性,一些对你来说可能是必需的,即使 skipMissingProperties 设置为 true。对于这种情况,你应该使用 @IsDefined() 装饰器。@IsDefined() 是唯一忽略 skipMissingProperties 选项的装饰器。
验证组
在不同情况下,您可能希望对同一个对象使用不同的验证模式。在这种情况下,您可以使用验证组。
重要提示 使用不会导致验证的组合(例如:不存在的组名)进行验证调用将导致未知值错误。当使用组进行验证时,提供的组组合应至少与一个装饰器相匹配。
import { validate, Min, Length } from 'class-validator';
export class User {
@Min(12, {
groups: ['registration'],
})
age: number;
@Length(2, 20, {
groups: ['registration', 'admin'],
})
name: string;
}
let user = new User();
user.age = 10;
user.name = 'Alex';
validate(user, {
groups: ['registration'],
}); // 这将不通过验证
validate(user, {
groups: ['admin'],
}); // 这将通过验证
validate(user, {
groups: ['registration', 'admin'],
}); // 这将不通过验证
validate(user, {
groups: undefined, // 默认
}); // 这将不通过验证,因为无论其组如何,所有属性都会被验证
validate(user, {
groups: [],
}); // 这将不通过验证,(等同于 'groups: undefined',见上文)
在验证选项中还有一个特殊的标志 always: true 可以使用。这个标志表示无论使用哪个组,这个验证都必须始终应用。
自定义验证类
如果你有自定义验证逻辑,你可以创建一个 约束类:
-
首先创建一个文件,比如叫做
CustomTextLength.ts,并定义一个新类:import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator'; @ValidatorConstraint({ name: 'customText', async: false }) export class CustomTextLength implements ValidatorConstraintInterface { validate(text: string, args: ValidationArguments) { return text.length > 1 && text.length < 10; // 对于异步验证,你必须在这里返回一个 Promise<boolean> } defaultMessage(args: ValidationArguments) { // 在这里你可以提供默认的错误消息,如果验证失败的话 return '文本 ($value) 太短或太长!'; } }
我们用 @ValidatorConstraint 装饰器标记了我们的类。
你也可以提供一个验证约束名称 - 这个名称将在 ValidationError 中作为 "错误类型" 使用。
如果你不提供约束名称 - 它将会自动生成。
我的类必须实现 ValidatorConstraintInterface 接口和它的 validate 方法,
定义了验证逻辑。如果验证成功,方法返回 true,否则返回 false。
自定义验证器可以是异步的,如果你想在一些异步操作后进行验证,只需在 validate 方法中返回一个内含布尔值的 promise 即可。
我们还定义了一个可选的方法 defaultMessage 它定义了一个默认的错误消息,
在装饰器的实现没有设置错误消息的情况下。
-
然后你可以在你的类中使用你的新验证约束:
import { Validate } from 'class-validator'; import { CustomTextLength } from './CustomTextLength'; export class Post { @Validate(CustomTextLength, { message: '标题太短或太长!', }) title: string; }
这里我们为 Post.title 设置了我们新创建的 CustomTextLength 验证约束。
-
正常使用验证器:
import { validate } from 'class-validator'; validate(post).then(errors => { // ... });
你也可以像这样向你的验证器传递约束:
import { Validate } from 'class-validator';
import { CustomTextLength } from './CustomTextLength';
export class Post {
@Validate(CustomTextLength, [3, 20], {
message: '博文标题不正确',
})
title: string;
}
并且从 validationArguments 对象中使用它们:
import { ValidationArguments, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator';
@ValidatorConstraint()
export class CustomTextLength implements ValidatorConstraintInterface {
validate(text: string, validationArguments: ValidationArguments) {
return text.length > validationArguments.constraints[0] && text.length < validationArguments.constraints[1];
}
}
自定义验证装饰器
你也可以创建自定义的装饰器。这是使用自定义验证的最优雅的方式。
我们来创建一个叫做 @IsLongerThan 的装饰器:
-
创建装饰器本身:
import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator'; export function IsLongerThan(property: string, validationOptions?: ValidationOptions) { return function (object: Object, propertyName: string) { registerDecorator({ name: 'isLongerThan', target: object.constructor, propertyName: propertyName, constraints: [property], options: validationOptions, validator: { validate(value: any, args: ValidationArguments) { const [relatedPropertyName] = args.constraints; const relatedValue = (args.object as any)[relatedPropertyName]; return typeof value === 'string' && typeof relatedValue === 'string' && value.length > relatedValue.length; // 你也可以在这里返回一个 Promise<boolean>,如果你想进行异步验证的话 }, }, }); }; } -
把装饰器投入使用:
import { IsLongerThan } from './IsLongerThan'; export class Post { title: string; @IsLongerThan('title', { /* 你也可以在自定义验证装饰器中使用其他验证选项,比如 "groups"。"each" 不支持 */ message: '文本必须比标题长', }) text: string; }
在你的自定义装饰器中你也可以使用 ValidationConstraint。
我们创建另一个自定义验证装饰器叫做 IsUserAlreadyExist:
-
创建一个 ValidationConstraint 和装饰器:
import { registerDecorator, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments, } from 'class-validator'; @ValidatorConstraint({ async: true }) export class IsUserAlreadyExistConstraint implements ValidatorConstraintInterface { validate(userName: any, args: ValidationArguments) { return UserRepository.findOneByName(userName).then(user => { if (user) return false; return true; }); } } export function IsUserAlreadyExist(validationOptions?: ValidationOptions) { return function (object: Object, propertyName: string) { registerDecorator({ target: object.constructor, propertyName: propertyName, options: validationOptions, constraints: [], validator: IsUserAlreadyExistConstraint, }); }; }
注意我们通过在验证选项中加入 { async: true } 标记了我们的约束为异步的。
-
并投入使用:
import { IsUserAlreadyExist } from './IsUserAlreadyExist'; export class User { @IsUserAlreadyExist({ message: '用户 $value 已经存在。请选择另一个名字。', }) name: string; }
useContainer使用服务容器
如果您想要在自定义验证器约束类中注入依赖性,验证器支持服务容器。以下是如何将其与typedi GitHub - typestack/typedi: Simple yet powerful dependency injection tool for JavaScript and TypeScript.集成的示例:
import { Container } from 'typedi';
import { useContainer, Validator } from 'class-validator';
// 在全局应用程序级别的某个地方执行这些操作:
useContainer(Container);
let validator = Container.get(Validator);
// 现在您可以在任何地方注入 Validator 类,它将来自容器
// 您还可以通过构造函数注入将类注入到您自定义的 ValidatorConstraint 中
同步验证
如果您想执行一个简单的非异步验证,您可以使用 validateSync 方法,而不是常规的 validate 方法。它的参数与 validate 方法相同。但请注意,这个方法 忽略 您所有的异步验证。
手动验证
Validator 中存在几种方法,允许执行非装饰器基础的验证:
import { isEmpty, isBoolean } from 'class-validator';
isEmpty(value); // 检查值是否为空
isBoolean(value); // 检查值是否为布尔类型
验证装饰器
| 装饰器 | 描述 | |
|---|---|---|
| **常见验证装饰器 ** | ||
@IsDefined(value: any) | 检查值是否已定义(!== undefined, !== null)。这是唯一忽略 skipMissingProperties 选项的装饰器。 | |
@IsOptional() | 检查给定值是否为空(=== null, === undefined),如果是,则忽略该属性的所有验证器。 | |
@Equals(comparison: any) | 检查值是否等于("===")比较值。 | |
@NotEquals(comparison: any) | 检查值是否不等于("!==")比较值。 | |
@IsEmpty() | 检查给定值是否为空(=== '', === null, === undefined)。 | |
@IsNotEmpty() | 检查给定值是否不为空(!== '', !== null, !== undefined)。 | |
@IsIn(values: any[]) | 检查值是否在允许值的数组中。 | |
@IsNotIn(values: any[]) | 检查值是否不在不允许值的数组中。 | |
| 类型验证装饰器 | ||
@IsBoolean() | 检查一个值是否为布尔值。 | |
@IsDate() | 检查值是否为日期。 | |
@IsString() | 检查值是否为字符串。 | |
@IsNumber(options: IsNumberOptions) | 检查值是否为数字。 | |
@IsInt() | 检查值是否为整数。 | |
@IsArray() | 检查值是否为数组。 | |
@IsEnum(entity: object) | 检查值是否是一个有效的枚举。 | |
| 数字验证装饰器 | ||
@IsDivisibleBy(num: number) | 检查数值是否可以被另一个数值整除。 | |
@IsPositive() | 检查值是否是大于零的正数。 | |
@IsNegative() | 检查值是否是小于零的负数。 | |
@Min(min: number) | 检查给定数值是否大于等于给定数值。 | |
@Max(max: number) | 检查给定数值是否小于等于给定数值。 | |
| 日期验证装饰器 | ||
| `@MinDate(date: Date | (() => Date))` | 检查值是否是在指定日期之后的日期。 |
| `@MaxDate(date: Date | (() => Date))` | 检查值是否是在指定日期之前的日期。 |
| 字符串类型验证装饰器 | ||
@IsBooleanString() | 检查字符串是否是布尔值(例如是 "true" 或 "false" 或 "1", "0")。 | |
@IsDateString() | @IsISO8601() 的别名。 | |
@IsNumberString(options?: IsNumericOptions) | 检查字符串是否为数字。 | |
| 字符串验证装饰器 | ||
@Contains(seed: string) | 检查字符串是否包含种子字符。 | |
@NotContains(seed: string) | 检查字符串是否不包含种子字符。 | |
@IsAlpha() | 检查字符串是否只包含字母 (a-zA-Z)。 | |
@IsAlphanumeric() | 检查字符串是否只包含字母和数字。 | |
@IsDecimal(options?: IsDecimalOptions) | 检查字符串是否是一个有效的十进制值。默认 IsDecimalOptions 为 force_decimal=False, decimal_digits: '1,', locale: 'en-US' | |
@IsAscii() | 检查字符串是否只包含 ASCII 字符。 | |
@IsBase32() | 检查字符串是否是 base32 编码。 | |
@IsBase58() | 检查字符串是否是 base58 编码。 | |
@IsBase64(options?: IsBase64Options) | 检查字符串是否是 base64 编码。 | |
@IsIBAN() | 检查字符串是否是 IBAN(国际银行账户号)。 | |
@IsBIC() | 检查字符串是否是 BIC(银行识别码)或 SWIFT 码。 | |
@IsByteLength(min: number, max?: number) | 检查字符串的长度(以字节为单位)是否在一个范围内。 | |
@IsCreditCard() | 检查字符串是否是信用卡。 | |
@IsCurrency(options?: IsCurrencyOptions) | 检查字符串是否是有效的货币金额。 | |
@IsISO4217CurrencyCode() | 检查字符串是否是 ISO 4217 货币代码。 | |
@IsEthereumAddress() | 检查字符串是否是以太坊地址,使用基本正则表达式。不验证地址校验和。 | |
@IsBtcAddress() | 检查字符串是否是有效的比特币地址。 | |
@IsDataURI() | 检查字符串是否是数据 URI 格式。 | |
@IsEmail(options?: IsEmailOptions) | 检查字符串是否是电子邮件。 | |
@IsFQDN(options?: IsFQDNOptions) | 检查字符串是否是完全限定域名(例如 domain.com)。 | |
@IsFullWidth() | 检查字符串是否包含任何全宽字符。 | |
@IsHalfWidth() | 检查字符串是否包含任何半宽字符。 | |
@IsVariableWidth() | 检查字符串是否包含全宽和半宽字符的混合。 | |
@IsHexColor() | 检查字符串是否是十六进制颜色。 | |
@IsHSL() | 检查字符串是否基于 CSS Colors Level 4 specification 的 HSL 颜色。 | |
@IsRgbColor(options?: IsRgbOptions) | 检查字符串是否是 rgb 或 rgba 颜色。 | |
@IsIdentityCard(locale?: string) | 检查字符串是否是有效的身份证代码。 | |
@IsPassportNumber(countryCode?: string) | 检查字符串是否是特定国家代码的有效护照号码。 | |
@IsPostalCode(locale?: string) | 检查字符串是否是邮政编码。 | |
@IsHexadecimal() | 检查字符串是否是十六进制数。 | |
@IsOctal() | 检查字符串是否是八进制数。 | |
@IsMACAddress(options?: IsMACAddressOptions) | 检查字符串是否是 MAC 地址。 | |
| `@IsIP(version?: "4" | "6")` | 检查字符串是否是 IP(版本 4 或 6)。 |
@IsPort() | 检查字符串是否是有效的端口号码。 | |
| `@IsISBN(version?: "10" | "13")` | 检查字符串是否是 ISBN(版本 10 或 13)。 |
@IsEAN() | 检查字符串是否是 EAN(欧洲文章编号)。 | |
@IsISIN() | 检查字符串是否是 ISIN(股票/证券识别符)。 | |
@IsISO8601(options?: IsISO8601Options) | 检查字符串是否是有效的 ISO 8601 日期格式。使用选项 strict = true 进行额外的有效日期检查。 | |
@IsJSON() | 检查字符串是否是有效的 JSON。 | |
@IsJWT() | 检查字符串是否是有效的 JWT。 | |
@IsObject() | 检查对象是否是有效的对象(null、函数、数组将返回 false)。 | |
@IsNotEmptyObject() | 检查对象是否不为空。 | |
@IsLowercase() | 检查字符串是否是小写。 | |
@IsLatLong() | 检查字符串是否是有效的纬度-经度坐标格式 lat, long。 | |
@IsLatitude() | 检查字符串或数字是否是有效的纬度坐标。 | |
@IsLongitude() | 检查字符串或数字是否是有效的经度坐标。 | |
@IsMobilePhone(locale: string) | 检查字符串是否为移动电话号码。 | |
@IsISO31661Alpha2() | 检查字符串是否为有效的ISO 3166-1 alpha-2官方指定的国家代码。 | |
@IsISO31661Alpha3() | 检查字符串是否为有效的ISO 3166-1 alpha-3官方指定的国家代码。 | |
@IsLocale() | 检查字符串是否为区域设置代码。 | |
@IsPhoneNumber(region: string) | 使用libphonenumber-js检查字符串是否为有效的电话号码。 | |
@IsMongoId() | 检查字符串是否为有效的MongoDB ObjectId的十六进制编码表示。 | |
@IsMultibyte() | 检查字符串是否包含一个或多个多字节字符。 | |
@IsNumberString(options?: IsNumericOptions) | 检查字符串是否为数字。 | |
@IsSurrogatePair() | 检查字符串是否包含任何替代对字符。 | |
@IsTaxId() | 检查字符串是否为有效的税务识别号。默认地区为en-US。 | |
@IsUrl(options?: IsURLOptions) | 检查字符串是否为URL。 | |
@IsMagnetURI() | 检查字符串是否符合magnet uri格式。 | |
@IsUUID(version?: UUIDVersion) | 检查字符串是否为UUID(版本3、4、5或全部)。 | |
@IsFirebasePushId() | 检查字符串是否为Firebase Push ID。 | |
@IsUppercase() | 检查字符串是否为大写。 | |
@Length(min: number, max?: number) | 检查字符串长度是否在某个范围内。 | |
@MinLength(min: number) | 检查字符串长度是否不少于给定数字。 | |
@MaxLength(max: number) | 检查字符串长度是否不超过给定数字。 | |
@Matches(pattern: RegExp, modifiers?: string) | 检查字符串是否匹配模式。可以是matches('foo', /foo/i)或matches('foo', 'foo', 'i')。 | |
@IsMilitaryTime() | 检查字符串是否为HH:MM格式的有效军事时间表示。 | |
@IsTimeZone() | 检查字符串是否表示有效的IANA时区。 | |
@IsHash(algorithm: string) | 检查字符串是否为哈希值。支持的类型有:md4, md5, sha1, sha256, sha384, sha512, ripemd128, ripemd160, tiger128, tiger160, tiger192, crc32, crc32b。 | |
@IsMimeType() | 检查字符串是否与有效的MIME类型格式匹配。 | |
@IsSemVer() | 检查字符串是否为Semantic Versioning Specification (SemVer)。 | |
@IsISSN(options?: IsISSNOptions) | 检查字符串是否为ISSN。 | |
@IsISRC() | 检查字符串是否为ISRC。 | |
@IsRFC3339() | 检查字符串是否为有效的RFC 3339日期。 | |
@IsStrongPassword(options?: IsStrongPasswordOptions) | 检查字符串是否为强密码。 | |
| 数组验证装饰器 | ||
@ArrayContains(values: any[]) | 检查数组是否包含给定数组的所有值。 | |
@ArrayNotContains(values: any[]) | 检查数组是否不包含给定数组的任何值。 | |
@ArrayNotEmpty() | 检查给定数组是否不为空。 | |
@ArrayMinSize(min: number) | 检查数组长度是否大于或等于指定数字。 | |
@ArrayMaxSize(max: number) | 检查数组长度是否不大于指定数字。 | |
@ArrayUnique(identifier?: (o) => any) | 检查数组值是否全唯一。对象的比较基于引用。可以指定函数,其返回值将用于比较。 | |
| 对象验证装饰器 | ||
@IsInstance(value: any) | 检查属性是否为传递值的实例。 | |
| 其他装饰器 | ||
@Allow() | 当没有指定其他约束时,防止移除属性。 |
定义无装饰器的验证模式
不使用装饰器的基于模式的验证已不再被 class-validator 支持。这个特性在 0.12 版本中被破坏,并且不会被修复。如果你对基于模式的验证感兴趣,你可以在 zod 自述文件的比较部分找到几个这样的框架。
验证纯对象
由于装饰器的本质,被验证的对象必须使用 new Class() 语法实例化。如果你有使用 class-validator 装饰器定义的类,并且你想验证纯 JS 对象(字面量对象或由 JSON.parse 返回的对象),你需要通过使用 class-transformer 将其转换为类的实例。
扩展
有几个扩展可以简化 class-validator 与其他模块的集成或添加额外的验证:
- class-transformer-validator:用于将
class-validator与 class-transformer 集成。 - class-validator-rule:一个用于
class-validator的规则扩展。 - ngx-dynamic-form-builder:一个用于 Angular 中动态表单构建器,用于与类验证器结合使用。
- ngx-reactive-form-class-validator:一个用于 Angular 中反应式表单的扩展,可用于类验证器。
- class-validator-extended:一个扩展了额外验证规则的
class-validator扩展。