rxjs:bindCallback返回一个错误的Observable签名

时间:2017-03-23 14:29:45

标签: angular typescript rxjs ngrx

我正在使用bindCallBackf(x, callback)转换为Observable<Action>f(x, callback)的位置:

f(
   data: StripeCardTokenData,
   responseHandler: 
   (
      status: number,
      response: StripeCardTokenResponse
   ) => void
): void;

所以,fStripe.card.createToken

其中StripeCardTokenResponse是:

interface StripeTokenResponse {
    id: string;
    client_ip: string;
    created: number;
    livemode: boolean;
    object: string;
    type: string;
    used: boolean;
    error?: StripeError;
}

另一方面,我正在使用Observable<Action>,其中Action是:

export interface Action {
    type: string;
    payload?: any;
}

所以,我在Observable<Action>声明了actions$

this.actions$
    .ofType('ADD_SOURCE')
    .switchMap(
      (action: Action) => {
        ((((1))))
    );

所以,在((((1))))我需要致电Stripe.card.createToken(data, callback)并根据callback(status, response)的{​​{1}}我需要返回response.error或{{1} }}

然而,我遇到了一些问题。

首先,我需要创建回调observable:

(Observable.of(<Action>{ type: 'ADD_SOURCE_SUCCESS' }))

尽管如此,打字稿告诉我(Observable.of(<Action>{ type: 'ADD_SOURCE_SUCCESS' }))是:

var callback = Observable.bindCallback(Stripe.card.createToken);

因此,callback(local var) callback: (v1: StripeCardTokenData) => Observable<number> callback在哪里处理它?<​​/ p>

我不知道我是否已经解释得那么好。我真的很挣扎,但我还没弄清楚如何解决它。

1 个答案:

答案 0 :(得分:1)

bindCallback可能很棘手。这完全取决于TypeScript推断类型并尝试匹配the numerous bindCallback signatures之一。

如果您的callback变量为(v1: StripeCardTokenData) => Observable<number>,则TypeScript似乎已将此功能与此签名匹配:

static create<T, R>(
  callbackFunc: (v1: T, callback: (result: R) => any) => any,
  selector?: void,
  scheduler?: IScheduler
): (v1: T) => Observable<R>;

回调将正确连接,但要访问response参数,您需要指定一个选择器:

var callback = Observable.bindCallback(
  Stripe.card.createToken,
  (status: number, response: StripeCardTokenResponse) => ({ status, response })
);

我建议明确使用回调参数类型(如上所述) - 否则,它们将被输入为any

指定选择器后,callback变量应具有以下类型:

(v1: StripeCardTokenData) => Observable<{ status: number; response: StripeCardTokenResponse; }>

你会使用这样的东西:

this.actions$
  .ofType('ADD_SOURCE')
  .switchMap(
    (action: Action) => {
      var callback = Observable.bindCallback(
        Stripe.card.createToken,
        (status: number, response: StripeCardTokenResponse) => ({ status, response })
      );
      return callback(action.payload/* or whatever */)
        .map(({ status, response }) => {
          var result: Action;
          if (response.error) {
            result = { type: "ADD_SOURCE_ERROR" };
          } else {
            result = { type: "ADD_SOURCE_SUCCESS" };
          }
          return result;
        });
    }
  );

我不熟悉Stripe API,因此不清楚Stripe.card.createToken是否需要绑定到Stripe.card。如果是这种情况,我建议不要使用Function.prototype.bind,因为它会返回any,这会阻止bindCallback的TypeScript推断类型。相反,您可以使用箭头功能:

var callback = Observable.bindCallback(
  (
    data: StripeCardTokenData,
    responseHandler: (status: number, response: StripeCardTokenResponse) => void
  ) => Stripe.card.createToken(data, responseHandler),
  (status: number, response: StripeCardTokenResponse) => ({ status, response })
);