Supabase 프로젝트에서 TypeScript 타입을 자동으로 관리하는 방법

이지·2024년 10월 19일
post-thumbnail

🤔 문제 상황

Supabase를 사용해 데이터를 가져올 때, 주로 다음과 같이 코드를 작성하게 된다.

const { data, error } = await supabase.from("review").select();

이때, dataany[]로 타입이 추론되기 때문에 이를 방지하기 위해 타입 파일을 만들어 직접 지정하는 방식을 사용하고 있었다.

export interface IReview {
  id: number;
  content: string;
  star_rating: number;
  product_id: number;
  images: null | string[];
  created_at: Date;
  user_id: string;
  order_item_id: number;
}

하지만 이 방법은 데이터베이스가 업데이트될 때마다 타입을 수정해야 하는 번거로움이 있었고 이를 자동으로 해결할 수 있는 방법에 대해 찾아보게 되었다.

🔍 해결방법: Supabase CLI 적용

Generating TypeScript Types | Supabase Docs

Supabase CLI를 사용하여 이 문제를 해결할 수 있다.

Supabase CLI?

  • Supabase 프로젝트를 관리하고, 데이터베이스 스키마, 환경설정, 마이그레이션 등을 제어할 수 있는 도구

Typescript 프로젝트와 통합하여 데이터베이스 스키마에 맞춘 타입을 자동으로 생성해주는 기능을 제공한다. 이를 통해 데이터베이스의 필드가 변경되거나 추가되었을 때, 수동으로 타입을 수정하지 않아도 되며, 최신 스키마에 맞춰 타입이 자동으로 업데이트된다.

Supabase CLI 적용하기

1. 설치

npm i supabase@">=1.8.1" --save-dev

2. 로그인

npx supabase login
  • 실행 결과
    웹에서 로그인이 완료되면 다음과 같은 결과를 확인할 수 있다.

3. 초기화

npx supabase init
  • 실행 결과

해당 명령어를 실행했을 때, Supabase CLI가 Deno와 관련된 설정을 VS Code에 적용할지 물어보는데

Deno? Node.js의 대안으로 만들어진 JS/TS 런타임

Supabase는 서버에서 Edge Functions와 같은 기능을 위해 Deno를 사용하는데 만약 해당 기능을 사용할 예정이라면 y, 아니라면 N를 선택하면 된다.

4. 데이터베이스 타입 파일 생성

npx supabase gen types --lang=typescript --project-id "$PROJECT_REF" --schema public > types/database.types.ts
  • $PROJECT_REF 에는 supabase의 프로젝트 세팅에서 Reference ID 입력
    • Supabase 대시보드의 설정에서 확인이 가능하다.
    • 또는 대시보드의 url의 맨 마지막에서도 확인 가능
  • 데이터베이스 스키마가 업데이트될 때마다 이 명령을 재실행해 타입을 최신 상태로 유지할 수 있다.
    • package.json에 스크립트를 추가하면 편리하다.

5. 타입 정의 적용

import { createClient } from '@supabase/supabase-js'
import { Database } from './database.types'

const supabase = createClient<Database>(process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY)

<Database>를 추가해줘야 한다.

활용

(리뷰) page.tsx

import MyReviews from "@/components/review/MyReviews";
import { createClient } from "@/utils/supabase/server";

export default async function ReviewPage() {
  const supabase = createClient();
  const { data, error } = await supabase.from("review").select();
  if (!data || data.length === 0) return <p>작성한 리뷰가 없습니다.</p>;
  if (error) {
    console.error("리뷰를 불러오는데 실패했습니다.", error);
    throw new Error("서버에서 문제가 생겼습니다.");
  }
  
  return (
    <div className="w-full">
      <h2 className="mb-8 text-3xl font-semibold text-center">리뷰조회</h2>
      <MyReviews reviews={data} />
    </div>
  );
}

MyReviews.tsx

import { Tables } from "@/types/database.types";

interface Props {
  reviews: Tables<"review">[];
}

export default function MyReviews({ reviews }: Props) {
  return (
    <ul>
      ...
    </ul>
  );
}

다음과 같이 database.types에서 가져와 활용할 수 있다.

자동으로 타입이 추론되는 모습을 확인할 수 있다. 🎊


참조
supabase + typescript DB schema 연동하기
supabase Type 명령어 한 줄로 자동생성하기

0개의 댓글