манипулирование функцией в typescript

#typescript #functional-programming

#typescript #функциональное программирование

Вопрос:

 export const wrapCountable = (func: Function): Function => {
    let result: Function amp; { __times?: number } = () => {
        //result.__times = result.__times || 0
        result.__times  
        let value = null
        try {
            value = func()
        } catch (e) {
            throw e
        }
        return value
    }
    result.__times = 0
    return result
}
 

Эта функция обернет другую функцию, которая передается в качестве параметра.

Проблема в том, что при strictNullChecks установке mode на true , в IDE будет ошибка.

введите описание изображения здесь

Единственное решение этой ошибки, которое я могу придумать, — добавить эту строку:

 result.__times = result.__times || 0
 

Однако я не думаю, что это идеальное решение. Тогда каков правильный способ?

Ответ №1:

Компилятор не понимает, что result.__times это определенно будет определено к моменту вызова функции arrow in result . Если вы предпочитаете не изменять отправленный JavaScript, вы можете использовать оператор утверждения, отличный от null ! , чтобы сообщить компилятору, что вы умнее, чем он есть, и это result.__times будет определено:

 export const wrapCountable = (func: Function): Function => {
    let result: Function amp; { __times?: number } = () => {
        result.__times!   // notice the ! here
        let value = null
        try {
            value = func()
        } catch (e) {
            throw e
        }
        return value
    }
    result.__times = 0
    return result
}
 

Это подавит ошибку. Однако это небезопасно для типов… вы можете закомментировать result.__times = 0 строку, и ошибка все равно будет подавлена. Утверждения типа, в том числе ! , позволяют лгать компилятору. Тем не менее, я ожидаю, что в этом случае вы можете принять обоснованное решение использовать утверждение.

При этом я бы, вероятно, свернул вашу функцию на что-то вроде

 const wrapCountable = <T>(func: () => T) => {
    const result = Object.assign(() => {
        result.__times  ;
        return func();
    }, { __times: 0 });
    return resu<
}

const eighteen = wrapCountable(() => 18);
// const eighteen: (() => number) amp; {__times: number}
console.log(eighteen()); // 18
console.log(eighteen()); // 18
console.log(eighteen.__times); // 2
 

с общим T , чтобы вы не теряли тип возвращаемого значения, и с Object.assign() таким, чтобы вам не нужно было разрешать __times быть undefined , и без этого try / catch block, который, похоже, ничего не делает (повторное throw использование того же исключения — это не операция, верно?).

В любом случае, надеюсь, это поможет. Удачи!