我正在尝试为节点的 Google Maps 帮助程序模块编写声明,但我遇到了库期望的 PromiseConstructorLike 问题,并正确返回它的“PromiseLike”实例方法(根据 https://googlemaps.github.io/google-maps-services-js/docs/module-@google_maps.html):
Promise function <optional> Promise constructor (optional).
所以我做了(精简到有趣的部分):
declare namespace GoogleMaps {
export interface CreateClientOptions<T> {
/** Promise constructor (optional). */
Promise?: T;
}
export interface GoogleMapsClient<T> {
directions<U>(query, callback?: ResponseCallback<U>): RequestHandle<U, T>;
}
export interface Response<U extends any> {
headers: any;
json: U;
status: number;
}
export interface RequestHandle<U, T extends PromiseLike<Response<U>>> {
asPromise(): T;
cancel(): void;
finally(callback: ResponseCallback<U>): void;
}
export type ResponseCallback<U> = (err: Error, result: Response<U>) => void;
export function createClient<T extends PromiseConstructorLike>(options: CreateClientOptions<T>): GoogleMapsClient<T>;
}
declare module '@google/maps' {
export = GoogleMaps
}
当然它不起作用,例如,如果我在 createClient
中使用 Bluebird as
import * as bluebird from 'bluebird'
import { createClient } from '@google/maps'
createClient({ Promise: bluebird }).directions({}).asPromise()/** no "then" here, just the static methods from Bluebird, like Bluebird.all */
那么问题是:
我是否可以提示 asPromise
方法从 bluebird 返回实例方法(then、catch、finally、reduce、timeout 等)而无需扩展 手动请求处理
接口(interface)?
更多信息(lib.d.ts
声明):
PromiseConstructorLike
是:
declare type PromiseConstructorLike = new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) => PromiseLike<T>;
PromiseLike
是:
interface PromiseLike<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then(
onfulfilled?: ((value: T) => T | PromiseLike<T>) | undefined | null,
onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): PromiseLike<T>;
}
最佳答案
您的声明包含一个编译错误,这是由于混淆了 Promise
实例 类型和 Promise
构造函数 类型。类型参数 T
在 GoogleMapsClient
用于填充T
在 RequestHandle
, 然而在 GoogleMapsClient
这代表 Promise
构造函数类型,而在 RequestHandle
它代表 Promise
实例类型。
您似乎打算根据 Promise
正确输入所有内容实例类型,PromiseLike<Response<U>>
, 其中U
是响应类型。然而,由于 U
事先不知道(即在调用 GoogleMapsClient.directions
之前),不幸的是这是不可能的。
如果你想调用then()
在 asPromise()
之后,您可以简单地更改 RequestHandle.asPromise
的返回类型至 PromiseLike<Response<U>>
并删除类型参数 T
:
export interface RequestHandle<U> {
asPromise(): PromiseLike<U>;
cancel(): void;
finally(callback: ResponseCallback<U>): void;
}
我个人也会添加约束 extends PromiseConstructorLike
输入参数 T
在两个CreateClientOptions
和 GoogleMapsClient
,所以传递的类型安全 Promise
构造函数不仅仅依赖于 createClient
中指定的约束.
总而言之,声明现在看起来像这样:
declare namespace GoogleMaps {
export interface CreateClientOptions<T extends PromiseConstructorLike> {
/** Promise constructor (optional). */
Promise?: T;
}
export interface GoogleMapsClient<T extends PromiseConstructorLike> {
directions<U>(query, callback?: ResponseCallback<U>): RequestHandle<U>;
}
export interface Response<U extends any> {
headers: any;
json: U;
status: number;
}
export interface RequestHandle<U> {
asPromise(): PromiseLike<Response<U>>;
cancel(): void;
finally(callback: ResponseCallback<U>): void;
}
export type ResponseCallback<U> = (err: Error, result: Response<U>) => void;
export function createClient<T extends PromiseConstructorLike>(options: CreateClientOptions<T>): GoogleMapsClient<T>;
}
declare module '@google/maps' {
export = GoogleMaps
}
通过这些声明,您的 bluebird
示例有效,您可以调用 then()
在 asPromise()
之后.
关于typescript - 如何在接口(interface)声明中使用 PromiseConstructorLike 实例的原型(prototype)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40481641/