#typescript
#typescript
Вопрос:
Пытаюсь написать функцию, которая возвращает корректно, когда происходит неожиданный «сбой». Думал о gonig с возвратом функции в стиле go для этого и вводил возврат как [Val, null] | [null, Error]
.
Однако при попытке ввода -защитите возвращаемое значение с помощью оператора if,
const [val, err] = myFunc(); // => [Val, null] | [null, Error]
if (err) {
handle(err);
return;
}
// At this point in code, return value has to be of type [Val, null]
doSomethingWith(val) // Error! Type 'null' is not assignable to type 'Val'
Кажется запутанным, учитывая, что аналогичный подход с объектами работает просто отлично (ссылка на игровую площадку)
const res = myFunc(); // => {type: 'Error'} | {type: 'Success', data: Val}
if (res.type === 'Error') {
handle(res);
return;
}
// In this example, res is correctly narrowed to {type: 'Success', data: Val}
doSomethingWith(res.data)
Кажется, объединение кортежей превращается в кортеж объединений,
От [Val, null] | [null, Error]
Для [Val | null, null | Error]
Это ожидаемое поведение? В чем причина этого и есть ли способ обойти это?
Ответ №1:
Это не превратилось в кортеж объединений — оно превратилось в две переменные с типами объединения, потому что вы разделили результат на две переменные. Typescript не отслеживает зависимости между типами разных переменных, поэтому ваша защита типа переменной err
не сужает и не может сужать тип переменной val
.
Решение: присвоите результат вашей функции одной переменной без деструктурирования, затем используйте result[0]
и result[1]
для ссылки на ее компоненты.
Ответ №2:
Теперь ваш код отлично работает в бета-версии TypeScript 4.6.
Демонстрация на игровой площадке
Информация об «Анализе потока управления для зависимых параметров» в объявлении бета-версии TS 4.6