使用 Zod 验证其中包含 Firestore DocumentReferences 的架构(使用默认值)?

问题描述 投票:0回答:2

我正在尝试使用 Zod 在使用 Firebase Firestore 时获得某种类型的理智(这是 Firestore 特有的)。假设我有这样的类型:

export type FooType = {
    id: string;
    relatedDocument: DocumentReference;
    otherRelatedDocument: DocumentReference;
};

我想用 Zod 模式验证它,就像这样:

export const fooTypeSchema = z.object({
    id: z.string(),
    relatedDocument: ???,
    otherRelatedDocument: ???,
});

如果我想做的只是验证,看起来我可以用这样的结构来完成它:

const dataConverterSchema = z.object({
  fromFirestore: z.function(),
  toFirestore: z.function(),
});

const docRefDocDataSchema =
  z.object({
    constructor: z.function(),
    converter: z.union([dataConverterSchema, z.null()]),
    firestore: z.object({ constructor }),
    id: z.string(),
    parent: z.object({ constructor }),
    path: z.string(),
    type: z.literal('document'),
    withConverter: z.function(),
  });

...但现在说我想做这样的事情:

export const fooTypeSchema = z.object({
    id: z.string(),
    relatedDocument: docRefDocDataSchema.default(() => doc(TABLE_NAME, DOC_ID)),
    otherRelatedDocument: docRefDocDataSchema.default(() => doc(TABLE_NAME, DOC_ID)),
});

这是行不通的。我怀疑有很多事情在起作用,但链中的第一个错误消息是关于

DocumentReference<DocumentData>
的构造函数如何是私有的(事实上,
doc()
是它的工厂函数)。

这里的最终目标是能够执行以下操作:

const newObj = fooTypeSchema.parse({id: "Foo"});
并获取一个有效的对象,其中填充了默认创建的 docRefs。我见过许多基于 Zod 的库声称可以处理 docRefs(Fireschema 和 Firesword),它们声称支持 docRefs,但它们似乎不处理默认值,只处理验证。

总体而言,Zod 似乎非常擅长处理原始类型,但是当我引入类(更不用说具有私有构造函数等花哨东西的类)时,它似乎变得很困难。

有办法做到这一点吗?

firebase google-cloud-firestore zod
2个回答
2
投票

我最初的想法是使用

z.instanceof
来解析文档引用,但这会遇到与您的架构相同的“私有构造函数”问题。

相反,我建议通过首先解析一个非常简单的值,然后使用带有

refine
的类型保护来解决这个问题,例如:

const docRefDocDataSchema = z.object({}).refine(
  (x: object): x is DocumentReference => x instanceof DocumentReference,
);

您可以按原样在原始架构中使用它。


0
投票

为什么不像下面这样呢?

z.custom<DocumentReference>(
    (val) => {
        return val instanceof DocumentReference;
    },
);
© www.soinside.com 2019 - 2024. All rights reserved.