#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
использование того же исключения — это не операция, верно?).
В любом случае, надеюсь, это поможет. Удачи!