如何设置模型类型n pouchdb upsert?

时间:2018-11-13 07:25:43

标签: typescript pouchdb upsert

看来我找不到解决办法。使用upsert on pouchdb我得到TS2345和或TS2339

我尝试像htis一样使用它。

db.upsert('id', doc => {
  doc.p = 'sample';
  return doc;
});

但是在doc.p上,我得到TS2339 Property 'p' does not exist on type '{} | IdMeta'

并且基于pouchdb-upsert / index.d.ts具有此定义

upsert<Model>(docId: Core.DocumentId, diffFun: UpsertDiffCallback<Content & Model>): Promise<UpsertResponse>;

所以我尝试了

db.upsert<{ p: string }>('id', doc => {
  doc.p = 'sample';
  return doc;
});

但是现在我得到TS2345TS2339。这是错误

Argument of type '(doc: {} | Document<{ p: string; }>) => {} | Document<{ p: string; }>' is not assignable to parameter of type 'UpsertDiffCallback<{ p: string; }>'.
   Type '{} | Document<{ p: string; }>' is not assignable to type 'false | "" | 0 | ({ p: string; } & Partial<IdMeta>) | null | undefined'.
     Type '{}' is not assignable to type 'false | "" | 0 | ({ p: string; } & Partial<IdMeta>) | null | undefined'.
       Type '{}' is not assignable to type '{ p: string; } & Partial<IdMeta>'.
         Type '{}' is not assignable to type '{ p: string; }'.
           Property 'p' is missing in type '{}'. (typescript-tide)

有人吗?请,谢谢。

更新

当我这样测试时:

  public test() {
    new PouchDB('test').upsert<{ p: string }>('id', doc => {
      doc.p = 'test string';
      return doc;
    })
  }

我得到这个:

Argument of type '(doc: Partial<Document<{ p: string; }>>) => Partial<Document<{ p: string; }>>' is not assignable to parameter of type 'UpsertDiffCallback<{ p: string; }>'.
   Type 'Partial<Document<{ p: string;; }>>' is not assignable to type 'false | "" | 0 | ({ p: string; } & Partial<IdMeta>) | null | undefined'.
     Type 'Partial<Document<{ p: string; }>>' is not assignable to type '{ p: string; } & Partial<IdMeta>'.
       Type 'Partial<Document<{ p: string; }>>' is not assignable to type '{ p: string; }'.
         Types of property 'p' are incompatible.
           Type 'string | undefined' is not assignable to type 'string'.
             Type 'undefined' is not assignable to type 'string'. (typescript-tide)

如果我这样做的话:

  public test2() {
    new PouchDB<{ p: string }>('test').upsert('id', doc => {
      doc.p = 'test string';
      return doc;
    })
  }

我得到这个:

Argument of type '(doc: Partial<Document<{ p: string; }>>) => Partial<Document<{ p: string; }>>' is not assignable to parameter of type 'UpsertDiffCallback<{ p: string; } & Partial<Document<{ p: string; }>>>'.
   Type 'Partial<Document<{ p: string; }>>' is not assignable to type 'false | "" | 0 | ({ p: string; } & Partial<Document<{ p: string; }>> & Partial<IdMeta>) | null | ...'.
     Type 'Partial<Document<{ p: string; }>>' is not assignable to type '{ p: string; } & Partial<Document<{ p: string; }>> & Partial<IdMeta>'.
       Type 'Partial<Document<{ p: string; }>>' is not assignable to type '{ p: string; }'.
         Types of property 'p' are incompatible.
           Type 'string | undefined' is not assignable to type 'string'.
             Type 'undefined' is not assignable to type 'string'. (typescript-tide)

1 个答案:

答案 0 :(得分:1)

问题的根源是如果文档不存在,并且您的diffFun收到参数{},并且该类型没有任何字段。我已将pull request提交给DefinitelyTyped,以将参数类型更改为Partial<Core.Document<Content & Model>>,这将更加有用,因为它将允许您分配给字段。 (请参见this answer,了解在合并请求请求之前使用修改后的声明的可能方法。)

但是,如果您将文档类型与必填字段一起使用,例如{ p: string },则在没有类型声明的情况下仍然无法返回doc,因为TypeScript仍然认为doc仅具有可选属性。您可以将文档类型指定为{ p?: string },然后代码将编译而不会出错。但是,如果您确实希望数据库中的所有文档都具有p属性,则最好使用{ p: string }并让每个diffFun使用类型断言或返回新对象,因此提醒您,如果文档不存在,则需要初始化所有必需的属性。