angular - hur använder jag `Observable.bindCallback()` med typescript


Jag har en Google Maps-riktningstjänst som jag försöker konvertera till ett Observable-mönster. Här är exemplet från 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);
      }
    });
  }

Jag försökte följande:

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)
      }
    )
  }

Varför avvisar TypeScript detta mönster?

Svar #1

Jag stötte precis på samma fel när jag försökte använda bindCallback. Jag löste det genom att uttryckligen ange typen på variabeln som pekar på resultatet av bindCallback. Jag använde bara "any". I ditt fall, försök

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

Detta förklarar dock inte varför Typescript avvisar det. Jag skulle gissa att det beror på att typdefinitionerna för resultatet av bindCallback är parameteriserade (dvs. de är generiskt typade). Titta på BoundCallbackObservable.d.ts för att se vad jag menar. Lägg märke till de flera parameteriserade definitionerna för alla de överlagrade "create"-metoderna (en av dem är till slut den som faktiskt anropas).

Svar #2

I rxjs 5 kan du åtgärda detta genom att uppfylla följande typsignatur.

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

Observera att det krävs två typer för att returnera en callback med en parametertyp T som returnerar Observable<R>.

Användning

type routeType = String

interface returnType = {
  res: any
  status: any
}

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

Nu är typen av route$ (v1: routeType) => Observable<observableType>

Relaterade artiklar