манипулирование функцией в машинописи - PullRequest
0 голосов
/ 15 апреля 2019
export const wrapCountable = (func: Function): Function => {
    let result: Function & { __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 установлено значение true, в IDE возникнет ошибка.

enter image description here

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

result.__times = result.__times || 0

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

1 Ответ

2 голосов
/ 15 апреля 2019

Компилятор не понимает, что 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 - то же самое исключение - нет, не так ли?).

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

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