Я начал изучать typescript, для практики решил написать класс для создания api сущностей. вот так выглядит базовый класс.
export type ApiResponse =
| { errors: Array<{ [key: string]: string }> }
| { data: any }
| { text: string };
type RequestData = {
url?: string;
method?: string;
data?: any;
};
abstract class Api {
protected readonly baseUrl: string;
protected readonly endPoint: string;
protected get url(): string {
return new URL(this.endPoint, this.baseUrl).toString();
}
protected constructor(baseUrl = '/', endPoint: string) {
this.baseUrl = baseUrl;
this.endPoint = endPoint;
}
protected async http({
url = '',
method = 'GET',
data = undefined,
}: RequestData): Promise<ApiResponse> {
try {
const response: Response = await fetch(
(new URL(url, this.url).toString()),
{ method, body: data }
);
return await response.json();
} catch (e) {
console.error(e.message);
return { text: e.message };
} finally {
// finnally
}
}
}
Как в целом все должно работать: я создаю апи сущность, наследуюясь от класса Api, например создаю сущность Post от Api.
В чем состоит мой ступор: у меня есть метод для http запроса, который должен в зависимости от разных ситуаций возвращать либо массив с ошибками, либо объект с данными, либо ошибку запроса. Естественно, при проектировании базового класса предугадать нельзя, что может прийти в запросе в поле data, имею ли я право в этом случае в поле data ставить тип
any?
export type ApiResponse =
| { errors: Array<{ [key: string]: string }> }
| { data: Array<any> }
| { text: string };
В дальнейшем этот самый ответ я уточню создав сущность:
import Api, { ApiResponse } from "@/api/Api";
export type Post {
userId: number;
id: number;
title: string;
body: string;
}
class ApiPost extends Api {
constructor(baseUrl: string, endPoint: string) {
super(baseUrl, endPoint);
}
async list(count?: number): Promise<boolean | Array<Post>> {
const response: ApiResponse = await this.http({
url: `${count ? `?_limit=${count}` : ''}`,
});
if (Array.isArray(response))
return response as Array<IPost>;
return false;
}
}
export default ApiPost;