Как динамически выводить свойства из ответа типа объединения в TypeScript?

Я работаю над проектом TypeScript, где мне нужно обрабатывать ответы API, который может возвращать различные структуры в зависимости от случаев успеха или ошибки. Ответы вводятся как объединение, и я хочу динамически проверять свойства без жесткого кодирования их имен.

Я использую useMutation React Query для обработки процесса входа в систему. Вот как я настроил свой крючок:

import { useMutation } from "@tanstack/react-query";
import { api } from "@/lib/api";
import { InferRequestType, InferResponseType } from "hono";
import { useNavigate } from "@tanstack/react-router";

const login = api.auth.login.$post;

type LoginRequest = InferRequestType<typeof login>;
type LoginResponse = InferResponseType<typeof login>;

const loginFunction = async (
  credentials: LoginRequest
): Promise<LoginResponse> => {
  const res = await login(credentials);
  if (!res.ok) throw new Error("Failed to login");
  const json = await res.json();
  return json;
};

export const useLoginMutation = () => {
  const navigate = useNavigate();
  const mutation = useMutation<LoginResponse, Error, LoginRequest>({
    mutationFn: loginFunction,
    mutationKey: ["auth", "login"],
    onSuccess: (data) => {},
    onError: (error) => {},
  });
  return mutation;
};

Вот как выводится LoginResponse:

type LoginResponse = {
    success: boolean;
    message: string;
} | {
    success: boolean;
    message: string;
} | {
    success: boolean;
    message: string;
    accessToken: string;
}

Когда ответ имеет код состояния 401 или 403, я получаю сообщение об успехе и сообщении. Когда 201: успех, сообщение, токен доступа.

При использовании обработчика onSuccess в хуке useMutation я хочу, чтобы TypeScript понимал, что данные имеют accessToken без явного жесткого кодирования имен свойств. 401 или 403 вызывают ошибку в loginFunction, которая затем вызывает onError в useMutation.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

для динамической обработки различных структур ответа вы можете использовать защиту типа, чтобы помочь TypeScript понять, какой тип объединения используется. Защита типа — это функция, которая проверяет, принадлежит ли объект определенному типу.

вот пример:

function hasAccessToken(response: LoginResponse): response is { success: boolean; message: string; accessToken: string } {
  return 'accessToken' in response;
}

Вы можете использовать этот тип защиты в своем обработчике onSuccess.

что-то вроде этого, чтобы вы не жестко кодировали имена свойств...

onSuccess: (data) => {
  if (hasAccessToken(data)) {
    // TypeScript now knows that data has an accessToken property
    console.info(data.accessToken);
  }
}

Другие вопросы по теме