API хариуны төрлүүд
Бодит төсөл дээр ажиллахад серверээс өгөгдөл авах нь маш түгээмэл. Гэвч fetch-ийн хариу ямар бүтэцтэй байхыг TypeScript мэдэхгүй — зөвхөн та мэднэ. Тиймээс API хариуны interface тодорхойлж, TypeScript-д заах хэрэгтэй.
Энэ хичээлд API хариуны төрлүүдийг хэрхэн зөв тодорхойлж, алдааг эрт илрүүлэх тухай сурна.
API хариуны interface тодорхойлох
Жишээ болгон нийтлэлийн жагсаалт буцаадаг API-тай ажиллая:
// types/api.ts
// Нэг нийтлэлийн бүтэц
interface Нийтлэл {
id: number;
title: string;
body: string;
userId: number;
}
// Хэрэглэгчийн бүтэц
interface Хэрэглэгч {
id: number;
name: string;
email: string;
username: string;
}
// API-ийн стандарт хариу (success эсвэл error)
interface ApiHариу<T> {
data: T;
success: boolean;
message: string;
}
Generic <T> хэрэглэснээр ApiHариу<Нийтлэл>, ApiHариу<Хэрэглэгч> гэх мэт олон янзын хариуг нэг interface-ээр илэрхийлж болдог.
fetch-тэй хамт хэрэглэх
// lib/api.ts
const API_URL = "https://jsonplaceholder.typicode.com";
// Нэг нийтлэл авах функц
async function нийтлэлАвах(id: number): Promise<Нийтлэл> {
const response = await fetch(`${API_URL}/posts/${id}`);
if (!response.ok) {
throw new Error(`Алдаа гарлаа: ${response.status}`);
}
const data: Нийтлэл = await response.json();
return data;
}
// Нийтлэлийн жагсаалт авах
async function нийтлэлүүдАвах(): Promise<Нийтлэл[]> {
const response = await fetch(`${API_URL}/posts`);
const data: Нийтлэл[] = await response.json();
return data;
}
// Ашиглах
const нийтлэл = await нийтлэлАвах(1);
console.log(нийтлэл.title); // TypeScript мэднэ, autocomplete ажиллана
response.json() нь Promise<any> буцаадаг тул заавал хажуугийн : Нийтлэл гэж зааж өгнө.
Алдааг зөв зохицуулах
// Алдааны бүтэц тодорхойлох
interface ApiАлдаа {
statusCode: number;
message: string;
error: string;
}
// Type guard ашиглан шалгах
function apiАлдааМөн(obj: unknown): obj is ApiАлдаа {
return (
typeof obj === "object" &&
obj !== null &&
"statusCode" in obj &&
"message" in obj
);
}
async function аюулгүйFetch<T>(url: string): Promise<T> {
try {
const response = await fetch(url);
const data: unknown = await response.json();
if (!response.ok) {
if (apiАлдааМөн(data)) {
throw new Error(data.message);
}
throw new Error("Серверийн алдаа гарлаа");
}
return data as T;
} catch (error) {
if (error instanceof Error) {
console.error("Хүсэлт амжилтгүй:", error.message);
}
throw error;
}
}
// Ашиглах — TypeScript <Нийтлэл[]> гэж мэдэнэ
const нийтлэлүүд = await аюулгүйFetch<Нийтлэл[]>(
"https://jsonplaceholder.typicode.com/posts",
);
Суpabase-тэй ажиллах
Next.js + Supabase хэрэглэхэд lib/supabase/types.ts файлаас үүсгэсэн төрлүүдийг импортолж ашиглана:
// lib/supabase/types.ts — Supabase автоматаар үүсгэдэг
export interface Database {
public: {
Tables: {
profiles: {
Row: {
id: string;
username: string | null;
xp: number;
streak: number;
created_at: string;
};
Insert: {
id: string;
username?: string | null;
xp?: number;
};
Update: {
username?: string | null;
xp?: number;
streak?: number;
};
};
};
};
}
// Ашиглах
import { createClient } from "@supabase/supabase-js";
import type { Database } from "@/lib/supabase/types";
const supabase = createClient<Database>(url, key);
// TypeScript профайлын бүх талбарыг мэднэ
const { data: профайл } = await supabase.from("profiles").select("*").single();
console.log(профайл?.xp); // number гэж TypeScript мэднэ
Дараагийн хичээлд:
React + TypeScript хамтад хэрхэн ажилладаг, component-ийг хэрхэн төрөлжүүлэх тухай сурна.