我正在编写es6-promise-pool
的定义以添加到DefinitelyTyped中,并对the discussion at GitHub进行了一些调整。该库可以使用可选的promise
参数,该参数指定用于返回的诺言的类(例如ES6-Promise
的polyfill或Bluebird
)。在内部,它只关心您可以call new Promise(…)
,因此这足以指定值的类型:
interface PromiseClass<A, P extends PromiseLike<A>> {
new(callback: (resolve: (value?: A | P) => void, reject: (reason?: any) => void) => void): P;
}
const bar: PromiseClass<number, Bluebird<number>> = Bluebird; // OK
麻烦的是指定选项的类型:
interface Options<A, P extends PromiseLike<A>, C extends PromiseClass<A, P>> {
promise?: C;
}
function foo<A, P extends PromiseLike<A>, C extends PromiseClass<A, P>>(options: Options<A, P, C>) { /* empty */ }
foo({ promise: Bluebird.resolve(3) });
这给了我一个错误:
Argument of type '{ promise: Bluebird; }' is not assignable to parameter of type 'Options, PromiseClass>>'. Types of property 'promise' are incompatible. Type 'Bluebird' is not assignable to type 'PromiseClass> | undefined'. Type 'Bluebird' is not assignable to type 'PromiseClass>'. Type 'Bluebird' provides no match for the signature 'new (callback: (resolve: (value?: {} | PromiseLike | undefined) => void, reject: (reason?: any) => void) => void): PromiseLike'.
(请注意,类型被推断为{}
。)
如果我手动指定类型:
foo<number, Bluebird<number>, PromiseClass<number, Bluebird<number>>>({ promise: Bluebird.resolve(3) });
我收到类似的错误:
Argument of type '{ promise: Bluebird; }' is not assignable to parameter of type 'Options, PromiseClass>>'. Types of property 'promise' are incompatible. Type 'Bluebird' is not assignable to type 'PromiseClass> | undefined'. Type 'Bluebird' is not assignable to type 'PromiseClass>'. Type 'Bluebird' provides no match for the signature 'new (callback: (resolve: (value?: number | PromiseLike | undefined) => void, reject: (reason?: any) => void) => void): Bluebird'.
这里是the relevant definitions from DefinitelyTyped,当正确推断类型时应该兼容:
type Resolvable<R> = R | PromiseLike<R>;
constructor(callback: (resolve: (thenableOrResult?: Resolvable<R>) => void, reject: (error?: any) => void, onCancel?: (callback: () => void) => void) => void);
对于上下文,这是我如何使用类型(省略了不相关的方法):
declare class PromisePool<
A, // the type of value returned by the source
P extends PromiseLike<A>, // the type of Promise returned by the source
P2 extends PromiseLike<A>, // the type of Promise specified in `options`
C extends PromisePool.PromiseClass<A, P2> // a helper class
> {
constructor(
source: IterableIterator<P> | P | (() => (P | undefined)) | A,
concurrency: number,
options?: PromisePool.Options<A, P2, C>
);
promise(): P2;
start(): P2;
}
declare namespace PromisePool {
interface PromiseClass<A, P extends PromiseLike<A>> {
new(callback: (resolve: (value?: A | P) => void, reject: (reason?: any) => void) => void): P;
}
interface Options<A, P extends PromiseLike<A>, C extends PromiseClass<A, P>> {
promise?: C;
}
}
如何指定Options
类型,以便:
new
个可行的承诺库(如上所述),并自动推断出类型Promise
PromisePool.promise
和PromisePool.start
的返回值答案 0 :(得分:0)
我误用了自己的类型,因为我以为Bluebird.resolve(3)
的功能与Bluebird
相同,尽管我出于区分两者的目的而陷入困境。无论如何,这可行:
import Bluebird = require("bluebird");
import ES6Promise = require("es6-promise");
interface PromiseClass<A, P extends PromiseLike<A>> {
new(callback: (resolve: (value?: A | P) => void, reject: (reason?: any) => void) => void): P;
}
interface Options<A, P extends PromiseLike<A>, C extends PromiseClass<A, P>> {
promise?: C;
}
function foo<A, P extends PromiseLike<A>, C extends PromiseClass<A, P>>(options: Options<A, P, C>, val: A): P {
return new options.promise((resolve, reject) => resolve(val));
}
const baz: Bluebird<number> = foo({ promise: Bluebird }, 5);
const quux: ES6Promise.Promise<number> = foo({ promise: ES6Promise.Promise }, 5);
我只需要将类作为promise
的值而不是实例进行传递。