Обход ограничений на машинопись - PullRequest
0 голосов
/ 07 января 2019

У меня есть код, который вполне приемлем с человеческой точки зрения. Но похоже, что системе типов машинописи трудно понять это. Есть ли умный способ подсказать компилятору, что в этой строке все нормально ?

  const isMustToRun: boolean = isFunc(condition) ? condition() : condition;

Код:

    export const noop = function() {
    };

    export const isFunc = function(obj: any): boolean {
      return typeof obj === 'function';
    };

    /**
     *
     * @param func funtion to run
     * @param condition condition check
     * @param args
     */
    export const runIf = function f(condition: (Function | boolean), func: Function, ...args: any[]) {
      return () => {
        const isMustToRun: boolean = isFunc(condition) ? condition() : condition;
        return isMustToRun ? func(...args) : noop();
      };
    };

Если бы я написал

typeof condition === 'function'

вместо вызова isFunc, тогда он работает. Но я не хочу повторять код ..

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Вам необходимо преобразовать isFunc в охрану пользовательского типа, и ваш код будет работать как положено .:

export const isFunc = function(obj: any): obj is Function {
  return typeof obj === 'function';
};

Я бы порекомендовал не использовать Function, хотя это не очень безопасно для типов, вы можете ограничить тип функции сигнатурой функции и использовать условный тип Extract, чтобы сохранить фактический тип передаваемого значения. функция для isFunc type-guard:

export const isFunc = function<T>(obj: T): obj is Extract<T, Function> {
    return typeof obj === 'function';
};

export const runIf = function f(condition: ((()=> boolean) | boolean), func: Function, ...args: any[]) {
    return () => {
        const isMustToRun: boolean = isFunc(condition) ? condition() : condition;
        return isMustToRun ? func(...args) : noop();
     };
};

Или полностью безопасная версия runIf, которая проверяет args на параметры func:

export const runIf = function f<T extends (...a: any)=>any>(condition: ((()=> boolean) | boolean), func: T, ...args: Parameters<T>): (()=>ReturnType<T>) {
    return () => {
    const isMustToRun: boolean = isFunc(condition) ? condition() : condition;
        return isMustToRun ? func(...args as any[]) : noop();
    };
};

function testFn(n: string) : number { return +n;}
runIf(true, testFn, "0"); //ok
runIf(true, testFn, 0); //err
0 голосов
/ 07 января 2019

Изменить тип возврата

export const isFunc = function(obj: any): boolean {
  return typeof obj === 'function';
};

будет is Function

export const isFunc = function(obj: any): obj is Function {
  return typeof obj === 'function';
};

Подробнее

Это называется определяемый пользователем тип защиты ?

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