为什么?要在将ng.IPromise
和Promise
混合在一起的大型代码库中查找错误。
我已经通过修改以下代码来完成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
扮演什么角色,甚至没有使用?