让我尝试解释一下情况:
- 要在 firestore 中创建新文档,我使用
collection
中的add
方法 - 为了保持类型安全,使用 typescript,我使用
withConverter
- 当我创建新文档时,我的对象没有 ID 属性
- 创建对象后,我就有了 ID 属性
bdw.. I'm using Mobx-state-tree
代码
让我一步步描述
mobx-state-tree定义的公司模型
const CompanyModel = types.model({
id: types.identifier,
name: types.string
});
我需要的类型
在我调用add
方法后,CompanyReference是我从firestore获取的
type CompanyReference = firebase.firestore.DocumentReference<
Instance<typeof CompanyModel>
>;
TCompanySnapshot 是我使用 add
方法发送到 firestore 的内容
type TCompanySnapshot = Omit<SnapshotIn<typeof CompanyModel>, "id">;
使用 withCOnverter
在 Firestore 之间进行转换
- 将数据发送到 firestore,只需使用常规
TCompanySnapshot
对象 - 从 firestore 接收一些对象(现在我有 ID 属性),转换为
CompanyModel
const createCompanyConverter: firebase.firestore.FirestoreDataConverter<Instance<
typeof CompanyModel
>> = {
toFirestore(modelObject: TCompanySnapshot): firebase.firestore.DocumentData {
return modelObject;
},
fromFirestore(
snapshot: firebase.firestore.QueryDocumentSnapshot<TCompanySnapshot>,
options: firebase.firestore.SnapshotOptions
): Instance<typeof CompanyModel> {
const data = snapshot.data(options);
return CompanyModel.create({
id: snapshot.id,
...data
});
}
};
问题
现在,当我尝试创建创建新公司的方法时,出现输入错误
function addCompany(
// companyData: SnapshotIn<typeof CompanyModel>,
companyData: TCompanySnapshot
): Promise<CompanyReference> {
const added = firestore
.collection("companies")
// .withConverter<Instance<typeof CompanyModel>>(createCompanyConverter)
.withConverter<TCompanySnapshot>(createCompanyConverter)
.add(companyData);
return added; // <<<<<------ ERROR HERE
}
Property 'id' is missing in type
您可以在 code sandbox 上检查此错误
https://codesandbox.io/s/firebase-typescript-mobx-state-tree-n9s7o?file=/src/index.ts
最佳答案
您遇到的问题是由于您使用 withConverter()
引起的,这正在更改 CollectionReference
的类型这样它与您的 CompanyReference
不匹配.
参见 Firestore#collection()
, CollectionReference#withConverter()
和 CollectionReference#add()
:
firestore
.collection("companies") // CollectionReference<DocumentData>
.withConverter<TCompanySnapshot>(createCompanyConverter) // CollectionReference<TCompanySnapshot>
.add(companyData); // Promise<DocumentReference<TCompanySnapshot>>
请注意DocumentReference<TCompanySnapshot> !== DocumentReference<Instance<typeof CompanyModel>>
.
如果您对对象的转换方式感到满意,则可以使用以下行强制覆盖类型:
return added as Promise<CompanyReference>;
但是,您应该更正您的 FirestoreDataConverter
实例。也不需要显式地重写所有内容,只需指定 firebase.firestore.FirestoreDataConverter<Instance<typeof CompanyModel>>
即可。因为结果的类型应该将适当的类型传播到其他对象。
const createCompanyConverter: firebase.firestore.FirestoreDataConverter<Instance<typeof CompanyModel>> = {
toFirestore(modelObject) {
const objToUpload = { ...modelObject } as firebase.firestore.DocumentData; // DocumentData is mutable
delete objToUpload.id; // make sure to remove ID so it's not uploaded to the document
return objToUpload;
},
fromFirestore(snapshot, options) {
const data = snapshot.data(options); // "as Omit<Instance<typeof CompanyModel>, "id">" could be added here
// spread data first, so an incorrectly stored id gets overridden
return CompanyModel.create({
...data,
id: snapshot.id
});
}
};
关于typescript - Firebase + Typescript - ID 属性和 withConverter 问题(创建没有 ID 属性的新文档),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66241871/