问题
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