通过向PromiseLike添加例外来修改es6 promise类型

时间:2018-11-26 17:34:59

标签: typescript es6-promise

为什么?要在将ng.IPromisePromise混合在一起的大型代码库中查找错误。

我已经通过修改以下代码来完成ng.IPromise的输入:

interface IPromise<T> {
    then<TResult>(successCallback: (promiseValue: T) => IPromise<TResult>|TResult, errorCallback?: null | undefined, notifyCallback?: (state: any) => any): IPromise<TResult>;
    // ...
}

对此:

interface IPromise<T> {
    then<TResult>(successCallback: (promiseValue: T) => IPromise<TResult>|TResult, errorCallback?: null | undefined, notifyCallback?: (state: any) => any): TResult extends Promise<any> ? never : IPromise<TResult>;
    // ...
}

但是原生的Promise类型更为复杂,因为它引入了PromiseLike类型来解析任何具有then方法的对象的结果:

interface PromiseLike<T> {
    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>;
}

interface Promise<T> {
    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
}

我想实现一种行为,其中PromiseLike之外的每个ng.IPromise都可以解决

已尝试简化键入以更好地理解它们。因此,基本上我们可以将问题简化为这样-如何修改以下类型:

interface Bar<T> {
    then<K>(f: (value: T) => K | Bar<K>): Bar<K>;
}

interface PartialFoo<T> {
    then<K>(f: (value: T) => K | PartialFoo<K>): PartialFoo<K>;
}

interface Foo<T> {
    then<K>(f: (value: T) => K | PartialFoo<K>): Foo<K>;
}

这样:

let a: Foo<string>;
let b: PartialFoo<number>;
let c: Bar<number>;

let x: Foo<string> = a.then(() => a); // is ok
let y: Foo<number> = a.then(() => b); // is ok
let z: never = a.then(() => c); // returns type never, so chaining anything else will give an error

还有另一件事,我不太了解Typescript的工作原理,为什么以这种方式修改接口:

interface PartialFoo<T> {
    then<K>(f: () => K | PartialFoo<K>): PartialFoo<K>;
}

interface Foo<T> {
    then<K>(f: () => K | PartialFoo<K>): Foo<K>;
}

let a: Foo<string>;
let x = a.then(() => a);
x

type是Foo<Foo<string>>,但在以下情况下:

interface Foo<T> {
    then<K>(f: () => K | Foo<K>): Foo<K>;
}

它仍然解析为Foo<string>value: T扮演什么角色,甚至没有使用?

0 个答案:

没有答案