изменить тип обещаний es6, добавив исключения в PromiseLike - PullRequest
0 голосов
/ 26 ноября 2018

Почему?Чтобы найти ошибки в большой базе кода, где 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 равен Foo<Foo<string>>, но в случае:

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

все равно разрешаетсяFoo<string>.Какую роль играет value: T, если она даже не используется?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...