У меня есть следующая функция для отмены обещаний.Как вы можете видеть, я определил интерфейс CancellablePromise
, который расширяет исходный Promise
, и у меня есть некоторые функции проверки типов, помеченные %checks
, чтобы проверить, является ли значение Promise или это уже отменяемое обещание.Основная функция makeCancellable
должна принимать Promise
в качестве аргумента и возвращать CancellablePromise
.Все работает , как и ожидалось, но мне пришлось использовать аннотации $FlowFixMe
в 3 местах, потому что Flow жаловался, что бы я ни пытался.(Прочтите комментарии в приведенном ниже коде, чтобы узнать, на что жалуется Flow).
Что меня больше всего беспокоит, так это самая первая проверка isCancellable
, в которой я проверяю, является ли обещание уже CancellablePromise
.Как ни странно, если я отмечу аргумент originalPromise
функции как any
, как CancellablePromise<*> | number
или как угодно, система проверки типов увидит, что функция isCancellable
является защитой типа, и перестанет жаловаться.Когда аргумент originalPromise
набирается так, как в примере кода ниже, каким-то образом Flow игнорирует тот факт, что isCancellable
является правильно типизированным защитником типа, и начинает жаловаться так же, как если бы защиты %checks
не было.
Буду признателен за любую помощь.У меня не было таких проблем, когда я использовал TypeScript некоторое время назад - там прекрасно работали охрана и типизация, но почему-то не получается заставить Flow сотрудничать.
interface CancellablePromise<T> extends Promise<T> {
cancel: Function
};
function isThenable(value: any): boolean %checks {
return typeof value === 'object' && 'then' in value;
}
function isCancellable(promise: any): boolean %checks {
return isThenable(promise) && 'cancel' in promise;
}
function makeCancellable(originalPromise: CancellablePromise<*> | Promise<*>): CancellablePromise<*> {
if (isCancellable(originalPromise)) {
// $FlowFixMe
return originalPromise; // <- complains here because Promise type does not have `cancel` method, ignores the isCancellable %checks
}
let resolvePromise;
let rejectPromise;
let cancelled = false;
const cancellable = new Promise((resolve, reject) => {
resolvePromise = resolve;
rejectPromise = reject;
});
// $FlowFixMe
// Complains here because Promise cannot have 'cancel' method
// Typecasting with (cancellable: CancellablePromise<*> does not work
cancellable.cancel = () => {
cancelled = true;
}
originalPromise.then(result => {
cancelled || resolvePromise(result);
}).catch(reason => {
cancelled || rejectPromise(reason);
});
// $FlowFixMe
// Complains here because Promise lacks 'cancel' method because adding the method and typecasting does not work
return cancellable;
};