Zod
Zod 是一个 TypeScript 和 JavaScript 库,用于建立类型安全的数据验证模式。它允许开发者以声明式的方式定义数据的结构,并通过创建的模式来验证 JavaScript 对象是否符合预期的类型定义。Zod 被设计成与 TypeScript 紧密集成,可以为验证的数据自动生成 TypeScript 类型。
zod日期类型如何接受ISO日期字符串?
在使用 `zod` 这个库来进行数据校验时,你可以使用 `zod.date()` 来创建一个日期的校验器。为了接受并验证一个 ISO 日期字符串,你需要使用 `zod.string()` 来确保输入是一个字符串,并结合 `zod.preprocess()` 来转换这个字符串为一个日期对象。这样做可以让你先验证字符串是符合 ISO 格式,再将其转化为 JavaScript 的 Date 对象。
具体实现步骤如下:
1. 使用 `zod.string()` 确保输入是一个字符串。
2. 使用 `zod.preprocess()` 将合法的 ISO 字符串转换为 Date 对象。
3. 使用 `zod.date()` 确保转换后的结果是一个有效的 Date 对象。
下面是一个具体的示例代码:
```javascript
import { z, ZodError } from 'zod';
const isoDateStringSchema = z.preprocess((arg) => {
if (typeof arg === 'string') {
const date = new Date(arg);
if (!isNaN(date.getTime())) {
return date;
}
}
return arg;
}, z.date());
try {
// 测试一个有效的 ISO 日期字符串
const result = isoDateStringSchema.parse('2021-12-01T14:48:00.000Z');
console.log(result); // 正确输出: 2021-12-01T14:48:00.000Z (日期对象)
} catch (e) {
if (e instanceof ZodError) {
console.log(e.errors); // 如果有错误,打印错误信息
}
}
try {
// 测试一个无效的 ISO 日期字符串
isoDateStringSchema.parse('not-a-date');
} catch (e) {
if (e instanceof ZodError) {
console.log(e.errors); // 正确捕获错误并打印
}
}
```
在这个示例中,`preprocess` 函数尝试将输入的字符串转换为 Date 对象。如果转换成功并且结果是一个有效日期(即 Date 对象不是 "Invalid Date"),则这个预处理函数返回该 Date 对象。之后,`z.date()` 验证这个对象确实是一个有效的 Date 对象。
这种方法允许你灵活地处理和验证 ISO 日期字符串,并确保它们在你的应用程序中以 Date 对象的形式正确使用。
阅读 54 · 7月21日 20:11
如何使用zod验证字符串文字类型
在使用Zod进行数据验证时,针对字符串文字类型(也称为字面量类型)的验证是一种常见需求。字符串文字类型是指某个具体的字符串值。在Zod中,可以使用`z.literal`来指定并验证特定的字符串值。
### 如何使用z.literal进行验证
首先,我们需要安装Zod库,如果你还没有安装,可以使用以下命令安装:
```bash
npm install zod
```
然后,你可以创建一个简单的验证模式来检查某个变量是否与指定的字符串文字相匹配。这里是一个具体的例子:
```javascript
import { z } from 'zod';
// 定义一个Zod模式,这里只接受字符串'admin'作为合法输入
const AdminRole = z.literal('admin');
// 使用这个模式来验证数据
try {
AdminRole.parse('admin'); // 有效,因为匹配了'admin'
console.log('验证通过!');
} catch (error) {
console.error('验证失败:', error);
}
try {
AdminRole.parse('user'); // 无效,因为不匹配'admin'
} catch (error) {
console.error('验证失败:', error);
}
```
### 扩展用例:使用union处理多个字符串文字
如果你需要验证的是多种固定字符串中的一种,可以使用`z.union`来组合多个`z.literal`:
```javascript
import { z } from 'zod';
// 定义一个模式,接受'admin', 'user', 或 'guest'作为合法输入
const UserRole = z.union([z.literal('admin'), z.literal('user'), z.literal('guest')]);
// 验证数据
try {
UserRole.parse('user'); // 有效
console.log('验证通过!');
} catch (error) {
console.error('验证失败:', error);
}
try {
UserRole.parse('manager'); // 无效
} catch (error) {
console.error('验证失败:', error);
}
```
### 总结
使用`z.literal`和`z.union`结合`z.literal`可以有效地为特定的字符串值或一组特定的字符串值建立验证规则。这种方法在处理配置项、权限角色等情况时非常有用,确保数据的准确性和程序的稳定性。
阅读 51 · 7月21日 20:06
如何在Zod中使用默认值创建可选属性
在Zod中,创建具有默认值的可选属性是一种常见的需求,尤其是在处理数据验证或设置配置对象时。Zod是一个TypeScript友好的库,用于构建强大的、类型安全的验证方案。它允许我们轻松地定义数据结构,同时提供默认值和类型安全的保障。
要在Zod中创建一个带有默认值的可选属性,我们可以使用`.optional()`和`.default()`方法来实现。下面是一个具体的例子,展示如何定义一个带有默认值的可选属性:
```typescript
import { z } from 'zod';
// 定义一个模式,其中包含一个带有默认值的可选属性
const PersonSchema = z.object({
name: z.string(), // 必需属性
age: z.number().optional(), // 可选属性,无默认值
isStudent: z.boolean().default(false), // 可选属性,有默认值
});
// 创建一个符合模式的对象
const person = PersonSchema.parse({
name: "张三",
// age 属性被省略
// isStudent 也被省略,但会使用默认值 false
});
console.log(person);
// 输出: { name: '张三', isStudent: false }
// 注意,如果没有提供 age,它将不会出现在结果对象中,因为它没有默认值
// 如果我们提供了所有值
const anotherPerson = PersonSchema.parse({
name: "李四",
age: 25,
isStudent: true,
});
console.log(anotherPerson);
// 输出: { name: '李四', age: 25, isStudent: true }
```
在这个例子中,`PersonSchema`定义了三个属性:`name`、`age` 和 `isStudent`。其中,`name`是一个必需的字符串,`age`是一个可选的数字,而`isStudent`是一个带有默认值`false`的布尔型可选属性。
使用`.default()`方法时,Zod会自动将属性标记为可选,所以我们不需要额外的`.optional()`调用。如果解析时没有提供`isStudent`的值,Zod将会使用默认值`false`。
通过这种方式,Zod不仅帮助确保数据的类型安全性,还能处理默认值和可选属性的情况,极大地简化了数据处理和验证的过程。
阅读 29 · 7月21日 20:03
如何从嵌套zod方案中省略某些值?
在使用Zod来构建和验证数据模型时,我们可能会遇到需要从嵌套模式中省略一些字段的情形。Zod提供了几种方法来修改或变换模式,其中包括省略字段。
### 使用`.omit()`方法
在Zod中,`omit()` 方法可以用来从模式中省略指定的字段。这在处理嵌套模式时尤其有用。让我们通过一个例子来看看如何实现:
假设我们有如下的嵌套Zod模式:
```javascript
import { z } from 'zod';
const User = z.object({
name: z.string(),
age: z.number(),
address: z.object({
street: z.string(),
city: z.string(),
zipCode: z.number()
})
});
// 希望省略address中的zipCode字段
const UserWithoutZipCode = User.omit({
address: {
zipCode: true
}
});
```
在上述代码中,我们定义了一个用户模式`User`,其中包含了一个名为`address`的嵌套对象。通过调用`User.omit()`并指定要省略的嵌套字段`zipCode`,我们创建了一个新的模式`UserWithoutZipCode`,其中不包含`zipCode`字段。
### 使用拆分和重组的方法
另一种方法是将嵌套的对象模式拆分为独立的模式,然后使用`omit()`单独省略所需字段,最后重新组合它们。这种方法在复杂的嵌套关系中更为灵活。
例如:
```javascript
const Address = z.object({
street: z.string(),
city: z.string(),
zipCode: z.number()
});
const AddressWithoutZipCode = Address.omit({ zipCode: true });
const User = z.object({
name: z.string(),
age: z.number(),
address: Address
});
const UserWithModifiedAddress = User.merge(z.object({
address: AddressWithoutZipCode
}));
```
在这个例子中,我们首先定义了一个独立的`Address`模式,然后创建了一个新的模式`AddressWithoutZipCode`来省略`zipCode`字段。之后,我们通过`merge()`方法将修改后的地址模式合并回用户模式中。
这两种方法都可以有效地从嵌套的Zod模式中省略指定字段,具体采用哪种方法取决于具体的需求和场景。
阅读 32 · 7月21日 20:01