Как предотвратить превращение объединения кортежей в кортеж объединений?

#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: