Возможно ли иметь дело с дополнительными свойствами, которые условны на основе логического значения в типе?

#typescript

Вопрос:

Моя текущая ситуация-это ответ сервера с логическим успехом и необязательными данными ответа или информацией об ошибке.

 type ServerResponse = {
  success: boolean;
  data?: { [key: string]: string };
  err?: { code: number, message: string };
}
 

Когда я хочу иметь дело с этим типом, это может быть немного неловко:

 const resp: ServerResponse = await fetch(...);

if(resp.success) {
   doSomething( resp.data?.foo );
} else {
   handleErr( resp.err?.message );
}
 

Это раздражает, когда приходится использовать ? «когда», я знаю, что data это всегда будет там, когда success === true и err всегда будет там, когда success === false

Я пытался изучить документацию по сопоставленным типам, но не нашел того, что мне нужно.

Является ли единственным или лучшим способом сделать это, изменив подход на игнорирование success ?

 const resp: ServerResponse = await fetch(...);

if(resp.data) {
   doSomething( resp.data.foo );
} else if(resp.err) {
   handleErr( resp.err.message );
}
 

Хотя это кажется разумным, я все равно хотел бы изучить более продвинутые способы набора текста.

Ответ №1:

Вы можете смоделировать это с помощью типов объединений.

Код для вашего варианта использования показан ниже,

 interface SuccessResponse {
    success: true;
    data: { [key: string]: string }
}

interface ErrorResponse {
    success: false;
    err: { code: number, message: string };
}

type ServerResponse = SuccessResponse | ErrorResponse;

fetch("http://your-endpoint.com")
    .then((response) => {
        return response.json();
    })
    .then((jsonResponse: ServerResponse) => {
        if(jsonResponse.success) {
            console.log(jsonResponse.data)
        } else {
            console.log(jsonResponse.err)
        }
    })
 

Версия для игровой площадки TS

Дайте мне знать, если вам это не ясно.

Комментарии:

1. Пожалуйста, подумайте о том, чтобы дополнить вашу ссылку на код также текстовой версией.