我有一个端点应该获取一个method
应该符合 Axios type 的参数Method
。
如何使用 Zod 创建一个架构来验证该值是否使用该类型Schema
?
import { Method } from 'axios';
const Schema = zod.object({
method: zod.someHowUseTheTypeFrom(Method),
});
Run Code Online (Sandbox Code Playgroud)
Method
Axios 包中的类型是:
export type Method =
| 'get' | 'GET'
| 'delete' | 'DELETE'
| 'head' | 'HEAD'
| 'options' | 'OPTIONS'
| 'post' | 'POST'
| 'put' | 'PUT'
| 'patch' | 'PATCH'
| 'purge' | 'PURGE'
| 'link' | 'LINK'
| 'unlink' | 'UNLINK'
Run Code Online (Sandbox Code Playgroud)
Sou*_*man 22
阅读您的评论,听起来您想确保您的架构与 axios 的类型同步Method
。我建议执行以下操作:
import { z } from 'zod';
import type { Method } from 'axios';
const methods: z.ZodType<Method> = z.enum(['get', 'GET', ...]);
Run Code Online (Sandbox Code Playgroud)
这至少会强制表达式右侧的模式解析有效的 axiosMethod
结果。axios
不幸的是,除非还导出包含与类型中的值相对应的字符串的数组,否则任何其他操作都可能无法实现Method
。
您正在寻找的原始内容z.something(<type here>)
无法工作,因为 zod 正在使用实际的运行时对象,并且诸如此类的类型Method
在运行时不存在。如果axios
导出一个包含方法的数组,那么这将是一个运行时值,您可以使用它(可能通过某种类型转换)来生成您的methods
架构(稍后会详细介绍)。
这种方法的另一个缺点是,类似这样的事情将进行类型检查:
const methods z.ZodType<Method> = z.enum(['get']);
Run Code Online (Sandbox Code Playgroud)
其原因在于类型在 TypeScript 中的工作方式。该enum
模式只会成功解析'get'
但由于文字'get'
是 中定义的较大联合类型的子类型Method
,因此生成的模式也是可分配的。
因此,我要提出的下一个选项感觉有点弄巧成拙,因为它需要重新声明 中的所有值Method
,但是,您可以继续使用该axios
Method
类型,并且您肯定会拥有一个解析所有值的模式在Method
(即,不屈服于上述问题):
import { z } from "zod";
import { Method } from "axios";
const METHOD_MAP: { [K in Method]: null } = {
get: null,
GET: null,
delete: null,
DELETE: null,
head: null,
HEAD: null,
options: null,
OPTIONS: null,
post: null,
POST: null,
put: null,
PUT: null,
patch: null,
PATCH: null,
purge: null,
PURGE: null,
link: null,
LINK: null,
unlink: null,
UNLINK: null
};
const METHODS = (Object.keys(METHOD_MAP) as unknown) as readonly [
Method,
...Method[]
];
const methods: z.ZodType<Method> = z.enum(METHODS);
Run Code Online (Sandbox Code Playgroud)
的类型断言METHODS
在这里是安全的,因为METHODS_MAP
不会导出,并且我们确切地知道它有哪些键。现在,如果缺少METHOD_MAP
任何值,该对象将导致类型错误,但这意味着生成的模式将解析所有值作为编译时强制执行的保证。Method
Method
小智 8
我发现 usingz.custom<ExistingType>()
对我有用,并且适合解决此类问题。
[已编辑] 根据@esteban-toress的说法,我们仍然需要在末尾添加一个验证函数,如下所示z.custom<ExistingType>((value) => //do something & return a boolean)
。否则,z.custom<ExistingType>()
只返回ZodAny
允许值的类型any
。
请参阅文档: https://zod.dev/?id =custom-schemas
归档时间: |
|
查看次数: |
62200 次 |
最近记录: |