带动态字段名称的类型化 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: