带动态字段名称的类型化 Zod 组合器
Typed Zod combinator with dynamic field name
我的 XML 到 JSON 库为单元素列表发出 {MyKey: T}
,为多元素列表发出 {MyKey: T[]}
。对应的 TypeScript 类型为 type XmlJsonArray<T, element extends string> = Record<element, T | T[]>
。我使用以下方法将其实现为 Zod 模式:
const XmlJsonArray = <T, element extends string>(element: element, schema: z.Schema<T>) => {
// TODO what is the idiomatic approach here?
const outerSchema: Record<element, z.Schema<T | T[]>> = {} as any;
outerSchema[element] = z.union([schema, z.array(schema)]);
return z.object(outerSchema);
};
有没有不使用 any
的方法来做到这一点?
通过@vriad:
const XmlJsonArray = <Key extends string, Schema extends z.Schema<any>>(
element: Key,
schema: Schema,
) => {
return z.object({}).setKey(element, z.union([schema, z.array(schema)]));
};
const test = XmlJsonArray('asdf', z.string());
Parsing works as expected:
// both work
test.parse({ asdf: 'hello' });
test.parse({ asdf: ['hello'] });
And type inference works too:
我的 XML 到 JSON 库为单元素列表发出 {MyKey: T}
,为多元素列表发出 {MyKey: T[]}
。对应的 TypeScript 类型为 type XmlJsonArray<T, element extends string> = Record<element, T | T[]>
。我使用以下方法将其实现为 Zod 模式:
const XmlJsonArray = <T, element extends string>(element: element, schema: z.Schema<T>) => {
// TODO what is the idiomatic approach here?
const outerSchema: Record<element, z.Schema<T | T[]>> = {} as any;
outerSchema[element] = z.union([schema, z.array(schema)]);
return z.object(outerSchema);
};
有没有不使用 any
的方法来做到这一点?
通过@vriad:
const XmlJsonArray = <Key extends string, Schema extends z.Schema<any>>( element: Key, schema: Schema, ) => { return z.object({}).setKey(element, z.union([schema, z.array(schema)])); }; const test = XmlJsonArray('asdf', z.string());
Parsing works as expected:
// both work test.parse({ asdf: 'hello' }); test.parse({ asdf: ['hello'] });
And type inference works too: