【问题标题】:What is the proper type for Angular DI injected superagent?Angular DI 注入的超级代理的正确类型是什么?
【发布时间】:2018-10-24 16:52:43
【问题描述】:

我正在尝试在使用 Angular DI (ngx) 的 node.js 应用程序中注入 Superagent。

import * as request from 'superagent';
 ... 
 {
    provide: request,
    useFactory: () =>
      request.agent()
        .timeout({deadline: 10000, timeout: 60000}),
  },

但我得到propertytimeoutdoes not exist on SuperAgent<SuperAgentRequest>。我尝试关注these docs,但 SuperAgent 似乎不是正确的类型。 request.agent() 的类型应该是 request.Request

我错过了什么?如何正确提供 request.Request 以便我可以全局配置它以使用相同的(注入的)实例?

【问题讨论】:

  • 顺便问一下,ngx 是什么?
  • ngx 是 Angular 2-6 的新命名法...
  • 啊,当然,我还以为是第三方库。

标签: javascript angular typescript dependency-injection superagent


【解决方案1】:

正如在 Superagent 类型中看到的那样,request.agent() 返回 SuperAgent<SuperAgentRequest> that doesn't have timeout method,这就是错误消息的内容。

虽然timeout 方法存在于Request 类型中,但它是响应的承诺。这就是引发此错误的原因。没有请求,也没有回应。 Superagent documentation 提供了timeout 的示例:

request
  .get('/big-file?network=slow')
  .timeout({
    response: 5000,  // Wait 5 seconds for the server to start sending,
    deadline: 60000, // but allow 1 minute for the file to finish loading.
  })

文档指出代理实例具有methods that set defaults,因此缺少类型。没有deadline 方法,用timeout 也没有意义,因为这是deadline timeout。

superagent 类型应该在本地增加,或者被改进并 PRed 到 DefinitiveTyped 存储库,或者就地固定:

 {
    provide: request,
    useFactory: () =>
      <SuperAgent<SuperAgentRequest>>request.agent()
        ['timeout'](30)
  }

我希望增强类型类似于(使用正则表达式处理原始Request 接口):

custom.d.ts

import * as request from 'superagent';

type CallbackHandler = (err: any, res: request.Response) => void;
type Serializer = (obj: any) => string;
type BrowserParser = (str: string) => any;
type NodeParser = (res: request.Response, callback: (err: Error | null, body: any) => void) => void;
type Parser = BrowserParser | NodeParser;

declare module "superagent" {
    interface ConfigurableSuperAgent<Req extends request.SuperAgentRequest> extends request.SuperAgent<Req> {
        accept(type: string): this;
        auth(user: string, name: string): this;
        buffer(val?: boolean): this;
        ca(cert: Buffer): this;
        cert(cert: Buffer | string): this;
        key(cert: Buffer | string): this;
        ok(callback: (res: Response) => boolean): this;
        on(name: 'error', handler: (err: any) => void): this;
        on(name: 'progress', handler: (event: ProgressEvent) => void): this;
        on(name: string, handler: (event: any) => void): this;
        parse(parser: Parser): this;
        pfx(cert: Buffer | string): this;
        query(val: object | string): this;
        redirects(n: number): this;
        retry(count?: number, callback?: CallbackHandler): this;
        serialize(serializer: Serializer): this;
        set(field: object): this;
        set(field: string, val: string): this;
        timeout(ms: number | { deadline?: number, response?: number }): this;
        type(val: string): this;
        use(fn: Plugin): this;
    }

    interface SuperAgentStatic extends request.SuperAgent<request.SuperAgentRequest> {
        agent(): ConfigurableSuperAgent<request.SuperAgentRequest>;
    }
}

【讨论】:

  • 这似乎与文档的“全局状态代理”部分相矛盾。
  • 究竟如何?我刚刚检查过,mentjoned 类型在最新的superagent@types/superagent 上按预期工作
  • TS 不允许从 ConfigurableSuperAgent 转换为 Request,即使它扩展了 SuperAgent
  • 好吧,主要问题是 .agent() 应该返回 Request 类型,因为它们应该是 Fluent API 流的一部分。
  • 我认为这没有问题,它应该可以按预期工作,请参阅 stackblitz.com/edit/typescript-ufufke?file=index.ts 。您可能会注意到编译器可以使用提供的类型。 agent() 不应该返回 Request 类型,因为它不做任何请求。一旦有一个agent().get(...),它将返回请求。这个问题没有提到 Fluent API,也不清楚问题可能是什么。无论如何,我认为 Superagent 应该是这样输入的,因为 as any 很难被认为是在 TS 中输入任何内容的正确方法,它是管理无法输入的东西的一种技巧。
猜你喜欢
  • 1970-01-01
  • 2020-05-31
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
  • 2020-01-21
  • 2017-12-19
  • 1970-01-01
相关资源
最近更新 更多