how do I use `Observable.bindCallback()` with typescript

不打扰是莪最后的温柔 提交于 2019-12-23 16:33:26

问题


I've got a google maps direction service I'm trying to convert to an Observable pattern. Here is the example from https://developers.google.com/maps/documentation/javascript/examples/directions-simple:

  function calculateAndDisplayRoute(directionsService, directionsDisplay) {
    directionsService.route({
      origin: document.getElementById('start').value,
      destination: document.getElementById('end').value,
      travelMode: 'DRIVING'
    }, function(response, status) {
      if (status === 'OK') {
        directionsDisplay.setDirections(response);
      } else {
        window.alert('Directions request failed due to ' + status);
      }
    });
  }

I tried the following:

import { Observable } from 'rxjs/Observable'; 
...
  // the callback version works
  getRoute (route: any) {
    const defaults = { 'travelMode': 'WALKING' };
    route = Object.assign(defaults, route);
    this._directionsService.route(
      route
      , (res:any, status:string) => {
          if (status == 'OK')
            this.displayRoute(res);
          else
            this.handleError(res)
       })
  }

  // the Observable version doesn't get past typescript
  getRoute$ (route: any) {
    const defaults = { 'travelMode': 'WALKING' };
    route = Object.assign(defaults, route);
    let route$ = Observable.bindCallback(
      this._directionsService.route
      , (res, status)=>{res, status}
    );
    // TS says, "Supplied parameters do not match any signature of call target
    route$( route ).subscribe(
      (resp:any)=>{
        // also, how do I throw an error from the selector func?
        if (resp.status == 'OK')
          this.displayRoute(resp.res);
        else
          this.handleError(resp.res)
      }
    )
  }

Why is typescript rejecting this pattern?


回答1:


I just dealt with the same error while trying to use bindCallback. I got around it by explicitly specifying the type of the var pointing to the result of bindCallback. I just used "any". In your case, try

let route$ : any = Observable.bindCallback(...)

This doesn't explain why Typescript rejects it though. I'd guess it's because the type definitions for the result of bindCallback are parameterized (i.e., they're generically typed). Look at BoundCallbackObservable.d.ts to see what I mean. Notice the multiple parameterized definitions for all those overloaded "create" methods (one of which is ultimately what gets invoked).




回答2:


In rxjs 5 you can fix this by fulfilling the following type signature.

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

Notice that it takes two types in order to return a callback with one parameter type T that returns Observable<R>.

Usage

type routeType = String

interface returnType = {
  res: any
  status: any
}

let route$: any = Observable.bindCallback<routeType, observableType>(this._directionsService.route, (res, status)=>{res, status})

Now the type of route$ is (v1: routeType) => Observable<observableType>



来源:https://stackoverflow.com/questions/39524472/how-do-i-use-observable-bindcallback-with-typescript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!