【问题标题】:How to set the model type n pouchdb upsert?如何设置模型类型 n pouchdb upsert?
【发布时间】:2019-04-15 23:34:59
【问题描述】:

我似乎无法找到解决方案。使用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)

【问题讨论】:

    标签: typescript pouchdb upsert


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢!顺便说一句,你的 PR 还没有合并,我只是修补了我的 index.d.ts 但我仍然得到了这个 (doc: Partial&lt;Document&lt;{ p: string; }&gt;&gt;) =&gt; void' is not assignable to parameter of type 'UpsertDiffCallback&lt;{ p: string; } &amp; void&gt; 。如果我不指定文档类型,我会得到这个(doc: Partial&lt;IdMeta&gt;) =&gt; void' is not assignable to parameter of type 'UpsertDiffCallback&lt;void &amp; {}&gt;
    • 您是否从diffFun 中删除了return doc 语句?该函数是返回新文档所必需的。如果不是这样,请使用您的最新代码更新问题,以便我重现问题。
    • 对不起,我没有添加return doc,但是当我添加时,请参阅上面的更新。
    • 啊。这是我在答案第二段中提到的问题。您需要在返回doc 之前使用类型断言,例如return &lt;{p: string}&gt;doc;
    猜你喜欢
    • 1970-01-01
    • 2018-11-24
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    相关资源
    最近更新 更多