Next.js / Next.js + TypeScript дэвшилтэт

Next.js + TypeScript дэвшилтэт

Next.js болон TypeScript хослуулах нь орчин үеийн fullstack хөгжүүлэлтийн хамгийн найдвартай арга юм. Та TypeScript-н үндсийг мэднэ — одоо Next.js-н App Router, Server Component, API route, params зэрэгт TypeScript-г зөв хэрэглэх аргыг сурна. Type safety нь алдааг runtime биш compile хийх үед илрүүлдэг тул ажил хийх явц хурдасдаг.

Page болон Layout-н төрөл

App Router-д page.tsx болон layout.tsx тус бүрт тодорхой props байдаг. Next.js 15-д params болон searchParams нь Promise тул заавал await хийх хэрэгтэй:

tsx
// app/courses/[courseSlug]/page.tsx
interface PageProps {
  params: Promise<{ courseSlug: string }>;
  searchParams: Promise<{ tab?: string }>;
}

export default async function CoursePage({ params, searchParams }: PageProps) {
  const { courseSlug } = await params;
  const { tab } = await searchParams;

  return (
    <main>
      <h1>{courseSlug}</h1>
      {tab && <p>Идэвхтэй таб: {tab}</p>}
    </main>
  );
}

Dynamic route сегмент олон байвал interface-г тохируулна:

tsx
// app/courses/[courseSlug]/[lessonSlug]/page.tsx
interface LessonPageProps {
  params: Promise<{
    courseSlug: string;
    lessonSlug: string;
  }>;
}

export default async function LessonPage({ params }: LessonPageProps) {
  const { courseSlug, lessonSlug } = await params;

  return (
    <article>
      <p>
        {courseSlug} / {lessonSlug}
      </p>
    </article>
  );
}

API Route Handler-н төрөл

Route handler бичихдээ NextRequest, NextResponse болон response-н өгөгдлийн interface-г тодорхойлно:

typescript
// app/api/progress/route.ts
import { NextRequest, NextResponse } from "next/server";

interface ProgressBody {
  lessonSlug: string;
  courseSlug: string;
  passed: true;
}

interface SuccessResponse {
  success: true;
}

interface ErrorResponse {
  error: string;
}

export async function POST(
  request: NextRequest,
): Promise<NextResponse<SuccessResponse | ErrorResponse>> {
  const body: ProgressBody = await request.json();

  if (!body.lessonSlug || !body.courseSlug) {
    return NextResponse.json({ error: "Талбар дутуу байна" }, { status: 400 });
  }

  // ... Supabase логик

  return NextResponse.json({ success: true });
}

Server Component дахь өгөгдлийн төрөл

Өгөгдлийн сангаас ирсэн өгөгдлийг interface болон generic-ээр тодорхойлно:

typescript
// lib/courses.ts
export interface Lesson {
  slug: string;
  title: string;
  order: number;
}

export interface Course {
  slug: string;
  title: string;
  description: string;
  color: string;
  isFree: boolean;
  lessons: Lesson[];
}

export async function getCourse(slug: string): Promise<Course | null> {
  // filesystem-с уншина
  try {
    const file = await import(`@/content/courses/${slug}/course.json`);
    return file.default as Course;
  } catch {
    return null;
  }
}

Server Action-н төрөл

Server Action нь 'use server' directive болон typed parameter ашигладаг:

typescript
// app/actions/progress.ts
"use server";

import { revalidatePath } from "next/cache";

interface CompleteInput {
  courseSlug: string;
  lessonSlug: string;
}

interface ActionResult {
  success: boolean;
  message: string;
}

export async function completeLesson(
  input: CompleteInput,
): Promise<ActionResult> {
  const { courseSlug, lessonSlug } = input;

  // progress хадгалах логик...

  revalidatePath(`/courses/${courseSlug}`);

  return { success: true, message: "Хичээл дуусгалаа!" };
}

Utility type ашиглах

TypeScript-н built-in utility type нь Next.js проектод маш их хэрэг болдог:

| Utility | Хэрэглэгдэх газар | | -------------- | ----------------------------------- | | Partial<T> | Optional update payload | | Pick<T, K> | Зөвхөн хэрэгтэй талбарыг сонгох | | Omit<T, K> | Тодорхой талбарыг хасах | | Record<K, V> | courseStyles, courseNums map | | Promise<T> | async Server Component return төрөл |

typescript
// lib/courses.ts
type CourseStyleKey = "border" | "glow" | "num" | "badge" | "accent" | "bar";

export type CourseStyle = Record<CourseStyleKey, string>;

export const courseStyles: Record<string, CourseStyle> = {
  green: {
    border: "border-[#14532d]",
    glow: "hover:shadow-[0_0_0_1px_#14532d]",
    num: "text-[#4ade80]",
    badge: "bg-[#052e16] text-[#4ade80]",
    accent: "text-[#4ade80]",
    bar: "bg-[#4ade80]",
  },
};

TypeScript-г зөв хэрэглэснээр IDE дотор autocomplete, hover-дэх type hint, compile error бүгд ажиллана. Эхэндээ type бичих нь удаан мэт санагдах боловч дараа нь алдаа засах цагийг маш их хэмнэдэг.

Дараагийн хичээлд:

Next.js апп-д олон хэл дэмжих i18n систем тохируулж, Монгол болон Англи хэлний агуулгыг хэрхэн удирдахыг сурна.