我正在使用firebase@5.5.8和typescript@3.1.4
每当我从Firestore创建文档时,都会得到一个firebase.firestore.DocumentReference
类型的对象
如果我调用get(options?: firebase.firestore.GetOptions|undefined)
,我将得到一个firebase.firestore.DocumentSnapshot
类型的对象
如果我致电data(options?: firebase.firestore.DataOptions|undefined)
,我将得到firebase.firestore.DocumentData对象或未定义的对象,如预期的那样
现在,在我的经理对象上,我知道我正在写数据库,因此我可以断言,无论从经理那里得到的DocumentData都将得到如图所示的Client
export interface Client {
name: string;
website?: string;
description?: string;
visible: boolean;
}
我想为我的经理对象创建一个表示该接口的接口。所以我尝试了:
export interface FirebaseDocumentSnapshot<T> extends $firebase.firestore.DocumentSnapshot {
data(options?: $firebase.firestore.SnapshotOptions | undefined): T|undefined
}
export interface FirebaseDocumentReference<T> extends $firebase.firestore.DocumentReference {
get(options?: $firebase.firestore.GetOptions | undefined): Promise<FirebaseDocumentSnapshot<T>>
}
我遇到的问题在这里:
const client: Client = mapClient(args);
const result: FirebaseDocumentReference<Client> = await $db.add(client);
错误是:
[ts]
Type 'DocumentReference' is not assignable to type 'FirebaseDocumentReference<Client>'.
Types of property 'get' are incompatible.
Type '(options?: GetOptions | undefined) => Promise<DocumentSnapshot>' is not assignable to type '(options?: GetOptions | undefined) => Promise<FirebaseDocumentSnapshot<Client>>'.
Type 'Promise<DocumentSnapshot>' is not assignable to type 'Promise<FirebaseDocumentSnapshot<Client>>'.
Type 'DocumentSnapshot' is not assignable to type 'FirebaseDocumentSnapshot<Client>'.
Types of property 'data' are incompatible.
Type '(options?: SnapshotOptions | undefined) => DocumentData | undefined' is not assignable to type '(options?: SnapshotOptions | undefined) => Client | undefined'.
Type 'DocumentData | undefined' is not assignable to type 'Client | undefined'.
Type 'DocumentData' is not assignable to type 'Client'.
Property 'name' is missing in type 'DocumentData'. [2322]
const result: FirebaseDocumentReference<Client>
我如何声明接口,以便知道结果对象的类型?
答案 0 :(得分:5)
@ gal-bracha的解决方案在TypeScript编译器将假设client
的类型为Client
的意义上将“起作用”,但是,如果错误数据以消防站。处理应用外部的任何数据时,一种更安全的解决方案是使用类似Yup的方法来明确验证数据:
import * as yup from "yup";
const clientSchema = yup.object({
name: yup.string(),
website: yup.string().url().notRequired(),
description: yup.string().notRequired(),
visible: yup.boolean()
});
// You can use this elsewhere in your app
export type Client = yup.InferType<typeof clientSchema>;
// Usage
const client = await clientSchema.validate(snapshot.data());
这更具防御性,因为如果出于某种原因,错误的数据最终存储在Firestore中,clientSchema.validate
将引发错误。在validate()
之后,可以保证client
是Client
,而不仅仅是告诉TypeScript编译器将其作为Client
进行处理,即使在运行时,它也可能不会是”。
答案 1 :(得分:0)
一个简单的解决方案是广播返回数据:
col1