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>
