我正在尝试为节点编写Google Maps帮助程序模块的声明,但我遇到了图书馆期望的PromiseConstructorLike问题,并将其返回" PromiseLike&#34 ;实例方法正确(根据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作为
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返回实例方法(然后,catch,finally,reduce,timeout等),而不必扩展RequestHandle
接口手动吗
更多信息(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>;
}
答案 0 :(得分:1)
您的声明包含编译错误,该错误源于混淆Promise
实例类型和Promise
构造函数类型。 T
中的类型参数GoogleMapsClient
用于填充T
中的RequestHandle
,但在GoogleMapsClient
中,这表示Promise
构造函数类型,而在{ {1}}它代表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
,以便传递{{1}的类型安全性构造函数不仅仅依赖于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
。
答案 1 :(得分:0)
随着Typescript 2.8的发布,新的“推断”关键字使这成为可能!它可以推断(并传递)复杂的嵌套声明,解释器将尝试为您获取信息,从而提供非常好的强类型化体验。
所以,如果要获取构造函数的类型
if (instance == null) {
throw new IllegalStateException("this application does not
inherit GlobalApplication"); " +
"}
return instance;
}
Step4)
g.setAdapter(new ImageAdapter(getGlobalApplicationContext()));
新的class MyPromise extends Promise<any> implements PromiseLike<any> {
add(s: number) {
s++
return this
}
dummy() {
return this
}
}
function typedFactory<
U extends PromiseConstructorLike,
>(u: U): InstanceType<U> {
return new u<void>(() => { }) as any
// this isn't needed since we are just trying to show the functionality,
// would be interfacing another library through types only, so that
// the compiler doesn't b*tch about it
}
typedFactory(Promise).then(() => { })
typedFactory(MyPromise).add(1).dummy().then(() => {})
实际上在InstanceType
中可用,并且定义为:
lib.es5.d.ts
它显示了type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
关键字的真实功能,您可以在https://www.typescriptlang.org/play/中尝试