supabase + typescript DB schema 연동하기

이슈

supabase로 사이드 프로젝트를 하고 있다. Talk table에서 데이터를 가져오기 위해 interface를 선언했고 ref에 generic으로 넘겼다.

예시 코드는 vue3 + typescript 환경이다.

export interface Talk {
  id: number
  speaker_id: string
  topic: string
  created_at: string
  duration: number
}

const talkList = ref<Talk[]>([])

supabase를 이용한 select 결과에서 data를 검사하면 string key와 any value를 가지는 일반적인 타입으로 추론되는 것을 확인할 수 있다. image

그래서 Talk interface와 맞지 않기 때문에 타입 에러가 난다.

image

설령 data type을 단언한다 해도, DB schema가 변하면 다시 작성해야 한다.

해결

supabase-cli를 활용하면 DB schema를 추출해 supabase sdk와 연동할 수 있다. 아래 링크를 보면 쉽게 따라갈 수 있다. https://supabase.com/docs/guides/api/rest/generating-types

PROJECT_REF를 찾는 게 처음에 어려웠는데, supabase dashboard를 들어간 후에 url에서 project 뒤에 오는 부분을 PROJECT_REF 칸에 넣어주면 된다.

https://supabase.com/dashboard/project/$PROJECT_REF
npx supabase gen types typescript --project-id "$PROJECT_REF" --schema public > src/types/supabase.ts

생성된 Database interface를 generic으로 넘긴다. image

이렇게 적용하고 기존 코드를 다시 보면 data 타입이 바뀐 것을 볼 수 있다! image

기존에 선언했던 Talk interface는 다음과 같이 Database interface에서 꺼내온 것으로 대체할 수 있다.

// /types/talk.ts
import type { Database } from './supabase'

export type Talk = Database['public']['Tables']['talk']['Row']

Written by@Donghoon Song
사람들의 꿈을 이어주는 코멘토에서 일하고 있습니다.

InstagramGitHubTwitterLinkedIn