Компилятор не понимает, что result.__times
определенно будет определяться ко времени вызова функции стрелки в result
.Если вы предпочитаете не изменять испускаемый JavaScript, вы можете использовать оператор ненулевого подтверждения !
, чтобы сообщить компилятору, что вы умнее его и что будет определено result.__times
:
export const wrapCountable = (func: Function): Function => {
let result: Function & { __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 result;
}
const eighteen = wrapCountable(() => 18);
// const eighteen: (() => number) & {__times: number}
console.log(eighteen()); // 18
console.log(eighteen()); // 18
console.log(eighteen.__times); // 2
суниверсальный T
, чтобы вы не потеряли тип возвращаемого значения, а с Object.assign()
, поэтому вам не нужно разрешать __times
быть undefined
, а без этого try
/ catch
блок, который, кажется, ничего не делает (повторное throw
- то же самое исключение - нет, не так ли?).
В любом случае, надеюсь, это поможет.Удачи!