Как вы определяете несколько типов выходов в итерируемом TypeScript? - PullRequest
2 голосов
/ 25 апреля 2020

У меня есть итеративная деструктуризация массива, которая работает, но не проверяет тип правильно. Я довольно новичок в TypeScript, поэтому я предполагаю, что я делаю что-то не так. Я использую TypeScript 3.8.2.

Этот пример работает, потому что проверка типов не выполняется, но раскомментирование последней строки вызывает ошибку ниже этого примера кода.

function MakeIterable<T> (a: T, b: number, c: boolean) {
    const result = [ a, b, c ]

    function* gen(): Generator<T | number | boolean, void, void> {
        let v
        while (v = result.shift()) {
            yield v
        }
    }

    return gen()
}

const [a, b, c] = MakeIterable(new Date(), 5, true)
console.log(a, b, c)
// a.setDate(0)

Ошибка вывод после раскомментирования a.setDate(0):

Error:(16, 7) TS2339: Property 'setDate' does not exist on type 'number | boolean | Date'.
  Property 'setDate' does not exist on type 'number'.

Кроме того, изменение определения Generator для ограничения его одним возвращаемым типом исправляет его, но второй и третий элементы итератора не будут тем типом, который TypeScript думает является. TypeScript считает, что все элементы должны быть объектами Date в этом случае.

Модифицированная строка примера:

function* gen(): Generator<T, void, void> {

Вопрос: Как правильно определить различные типы значений что вернулось из итератора? В идеале типы в порядке (в данном случае T, number, boolean) были бы хорошими.

1 Ответ

1 голос
/ 25 апреля 2020

Определение типа для Generator или Iterator не поддерживает упорядоченную последовательность типов возврата - более строгие генераторы . Но также, по логике вещей, упорядоченная последовательность типов возврата будет нарушаться чаще, чем нет.

Это будет работать только в простейших случаях, когда next() вызывается в пределах одной и той же области видимости / файла последовательно, до последовательности концы. Данный пример слишком тривиален, так что генератор может быть полностью опущен.

Например, если next() вызывается через обработчик события, или генератор используется несколькими компонентами, указание порядка типов потенциально может привести к времени выполнения ошибки. Следовательно, тип объединения T | number | boolean является подходящим выходом для генератора.

Правильный подход, охватывающий все варианты использования, заключается в использовании защиты типа для возвращаемых значений.

if (a instanceof Date) {
    a.setDate(0);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...