Объясните, как вы бы написали функцию на TypeScript, которая использует fetch
для выполнения вызова API и возвращает промис (Promise
).
Подсказки:
- Подумайте, как вы бы могли обработать обобщённый тип данных, возвращаемых API.
- Подумайте, как бы вы управляли ошибками в функции
async/await
. - Возможно ли использование типа
Awaited
, чтобы вывести разрешённый тип промиса?
Превосходя ожидания:
- Как создать пользовательский класс ошибок для более точной обработки ошибок при вызовах API.
- Использование
Promise.all
для эффективной обработки нескольких асинхронных операций. - Как типы-утилиты TypeScript, такие как
ReturnType
, могут использоваться для вывода типов возвращаемых значений функций.
Для написания функции в TypeScript, которая использует fetch
для выполнения API-запросов и возвращает промис, следуйте этим шагам:
-
Определение типа ответа: Начните с определения типа данных, которые ожидается вернуть API. Используйте интерфейс или алиас типа для явного определения структуры ответа API. Например:
interface ApiResponse { id: number; name: string; email: string; }
-
Типизация функции fetch: Создайте функцию, которая использует
fetch
для выполнения API-запроса. Используйте обобщения (generics), чтобы обеспечить гибкость в типе ответа. Функция должна возвращать промис ожидаемого типа ответа.function fetchData<T>(url: string): Promise<T> { return fetch(url) .then(response => { if (!response.ok) { throw new Error('Сеть вернула некорректный ответ'); } return response.json(); }); }
-
Async/Await с обработкой ошибок: Используйте синтаксис
async/await
для более чистого и читабельного асинхронного кода. Реализуйте обработку ошибок с помощью блоковtry/catch
для управления исключениями.async function getData<T>(url: string): Promise<T> { try { const response = await fetch(url); if (!response.ok) { throw new Error('Ошибка получения данных'); } const data: T = await response.json(); return data; } catch (error) { console.error('Ошибка получения данных:', error); throw error; } }
-
Использование типа Awaited: Используйте тип
Awaited
, чтобы вывести тип результирующего значения промиса. Это особенно полезно в сложных цепочках промисов или при использованииPromise.all
.type ApiResponseType = Awaited<ReturnType<typeof getData<ApiResponse>>>;
-
Пользовательский класс ошибок: Создайте пользовательский класс ошибок, чтобы обеспечить более точную обработку ошибок и контекст об ошибках при выполнении API-запросов. Это помогает различать различные типы ошибок.
class ApiError extends Error { constructor(public statusCode: number, message: string) { super(message); this.name = 'ApiError'; } } async function getDataWithCustomError<T>(url: string): Promise<T> { try { const response = await fetch(url); if (!response.ok) { throw new ApiError(response.status, 'Ошибка получения данных'); } const data: T = await response.json(); return data; } catch (error) { if (error instanceof ApiError) { console.error('Ошибка API:', error.statusCode, error.message); } else { console.error('Непредвиденная ошибка:', error); } throw error; } }
-
Обработка нескольких промисов с Promise.all: При работе с несколькими асинхронными операциями используйте
Promise.all
, чтобы выполнить их одновременно. Определите результат с помощью массива ожидаемых типов ответа.async function fetchMultipleData<T>(urls: string[]): Promise<T[]> { try { const responses = await Promise.all(urls.map(url => fetch(url))); const data = await Promise.all(responses.map(response => response.json())); return data; } catch (error) { console.error('Ошибка получения данных:', error); throw error; } }
-
Утилитарные типы для вывода типов возвращаемых значений: Используйте утилитные типы TypeScript, такие как
ReturnType
, чтобы вывести тип возвращаемого значения функций. Это обеспечивает согласованность и уменьшает избыточность в объявлениях типов.type FetchDataReturnType = ReturnType<typeof getData<ApiResponse>>;
Следуя этим рекомендациям, вы обеспечиваете надежность, поддерживаемость и типо-безопасность кода при взаимодействии с удаленным API.