[TypeScript] Generating TypeScript Types 사용하기

정다롱·2024년 10월 22일

내일배움캠프 TIL

목록 보기
33/39

🖥️ supabase Generating TypeScript Types

ts로 프로젝트를 진행하면서 온갖 라이브러리, API에 대한 type을 작성하기가 참 번거롭고 귀찮았는데, 이런 타입을 사람들이 정리해서 공유하고 있다는 걸 얼마 전에 알게 되었다.

supabase에서도 이러한 것들을 지원해주고 있었는데, 내 프로젝트에서 생성한 테이블에 대한 type을 파일로 받아볼 수 있는 기능이 있다.

공식 문서 확인하기

🚩 타입 생성 방법

  1. 터미널에서 supabase 설치
    yarn add supabase --dev
    해당 명령어를 사용하여 클라이언트 라이브러리를 설치한다.
  1. supabase 로그인 인증하기
    yarn supabase login
    터미널에 명령어를 입력하면
    Hello from Supabase! Press Enter to open browser and login automatically.
    이런 메세지가 뜬다. 시키는 대로 Enter를 누르면 브라우저 창이 뜨고 로그인을 진행하면 된다. 나는 이미 로그인을 해둔 상태라서 바로 인증이 됐다.
  • 이 단계를 모르고 계속 타입 생성을 시도해서 에러가 떴다. 프로젝트에 대한 권한이 있는지 확인해야 프로젝트에 대한 타입을 제공해주는게 당연한데, 아예 생각을 못하고 있었다.

2번 과정 진행 후
You are now logged in. Happy coding! Done in 9.39s.
이런 메세지가 떴다면 3번을 진행하면 된다.
나는 바로 떠서 해당 과정에서 에러가 생기는지 잘 모르겠지만... 에러가 생긴다면 그 부분은 검색해보시길 .....

  1. 타입 파일 생성하기
    yarn supabase gen types typescript --project-id 프로젝트ID > database.types.ts
    프로젝트ID 부분에 자신의 프로젝트 ID를 입력하면 된다.
    프로젝트 ID는 아래 경로를 통해 받아볼 수 있다.
    Dashboard => 타입이 필요한 프로젝트 클릭 => 왼쪽 메뉴에서 Project Settings => General => Reference ID

3번까지 완료 되면 루트 경로에 database.types.ts 파일이 생긴 걸 확인할 수 있다. 맨 위, 아래에 명령어랑 완료 시간이 함께 나오는데 그 부분은 지우고 사용하면 된다.

🚩 타입 사용 방법

공식 문서에도 나와있듯이 타입을 사용하는 방법은 간단하다.

import { Database, Tables, Enums } from "./database.types.ts";

// Before 😕
let movie: Database['public']['Tables']['movies']['Row'] = // ...

// After 😍
let movie: Tables<'movies'>

방법이 두 개 나와있는데
Before의 경우 경로를 하나하나 지정하여 타입을 사용하는 방법이고
After의 경우Tables 유틸리티 타입이 내부적으로 복잡한 타입 경로를 처리하여 바로 필요한 타입을 사용할 수 있다.

하지만 정확히 두 방법이 같은 타입을 불러오고 있는 건 아니다.

supabase에서는 한 테이블에서 여러 타입을 지원하는데

export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[]

export interface Database {
  public: {
    Tables: {
      movies: {
        Row: {               // the data expected from .select()
          id: number
          name: string
          data: Json | null
        }
        Insert: {            // the data to be passed to .insert()
          id?: never         // generated columns must not be supplied
          name: string       // `not null` columns with no default must be supplied
          data?: Json | null // nullable columns can be omitted
        }
        Update: {            // the data to be passed to .update()
          id?: never
          name?: string      // `not null` columns are optional on .update()
          data?: Json | null
        }
      }
    }
  }
}

보이는 것처럼 row, insert, update 타입을 제공한다.
row의 경우는 읽어올 때, insert, update는 각 역할을 수행할 때 사용할 수 있다.

After의 Tables<'movies'> 는 기본적으로 movies의 row를 가져오고 있고,
Tables<'movies', 'Insert'> 이런 식으로 다른 타입을 지정하여 사용할 수 있다.

0개의 댓글