☠️
【Supabase × TypeScript】JavaScript Client Libraryでデータを取得する際に遭遇する落とし穴と対策
はじめに
この記事は、Supabaseを使ってWebアプリを作成したことがある方を対象としています。
現象は以下のバージョンで再現します。
package.json
"@supabase/supabase-js": "^2.33.2"
SupabaseのJavaScript Client Libraryとは
例えば、以下のSQL処理は
select id, title, content from articles;
JavaScript Client Libraryを使うことによって
const { data: articles, error } = await supabase
.from('articles')
.select('id,title,content');
と書けます。
遭遇した落とし穴
欲しいデータが動的に変わる場合があったとして、以下のように書きたくなることがあるかもしれません。
let fields = 'id,title,content1';
const session = await getSession();
// ログイン済みの場合
if (session) {
fields += ',content2';
}
const { data: article, error } = await supabase
.from('articles')
.select(fields)
.eq('slug', params.slug)
.single();
一見何も問題ないように見えますが、article
の型を確認すると、GenericStringError
となっています。
Issueのやり取りを見ていくと、Supabaseの中の人が以下のように回答しています。
select()
に渡された実引数が文字列リテラルではなく文字列変数の場合、正しく機能しないとのことです。
中の人はselect(fields as any)
とすることで回避できると説明していますが、これをやっても解決しません。
解決策
as any
ではなくas '*'
とすることで解決します。
これについて、Issueでも扱いづらさが指摘されています。
const { data: article, error } = await supabase
.from('articles')
.select(fields as '*')
.eq('slug', params.slug)
.single();
Discussion