svelte - Typescript-feil med SvelteKit og Supabase-datahenting (Type 'null' kan ikke tilordnes typen 'ArrayLike')
Jeg har et SvelteKit-prosjekt satt opp som autentiserer med Supabase. Jeg brukte denne veiledningen for det. Autentiseringen og henting av data fungerer fint så langt. Faktisk, når det gjelder selve appen, fungerer alt som forventet. Jeg får bare en irriterende Typescript-feil som jeg ikke får bort.
Jeg henter dataene i denne filen:
// <!-- routes/playlists/+page.ts -->
import type { PageLoad } from './$types';
import { redirect } from '@sveltejs/kit';
export const load: PageLoad = async ({ parent }) => {
const { supabase, session } = await parent();
if (!session) {
throw redirect(303, '/');
}
const { data: playlist } = await supabase.from('playlist').select('*');
return {
user: session.user,
playlist
};
};
Og den tilsvarende Svelte-filen for å vise det:
<!-- routes/playlists/+page.svelte -->
<script lang="ts">
import type { PageData } from './$types';
import { json } from '@sveltejs/kit';
export let data: PageData;
</script>
<main>
<div>{data.user.email}</div> <!-- This works fine! -->
<ul>
{#each data.playlist as pl} <!-- Typescript complains about this -->
<li>
{pl.spotify_uri} <!-- and this -->
</li>
{/each}
</ul>
</main>
Nå er dette feilene jeg får:
'pl' is of type 'unknown'.Og
Argument of type '{ created_at: string; follower_count: number; last_auto_renewal: string; last_manual_renewal: string; playlist_id: number; spotify_uri: string; user_id: string | null; }[] | null'
is not assignable to parameter of type 'ArrayLike<unknown>'.
Type 'null' is not assignable to type 'ArrayLike<unknown>'.
Men, som jeg sa, på nettsiden vises alt akkurat som forventet, og jeg får ingen andre feil, det virker bare som om Typescript ikke er fornøyd. Det som også er merkelig er at data.user.email ikke gir noen feil i det hele tatt.
De automatisk genererte typene fra supabase ser slik ut:
// $lib/supabase/schema.ts
export interface Database {
public: {
Tables: {
playlist: {
Row: {
created_at: string
follower_count: number
last_auto_renewal: string
last_manual_renewal: string
playlist_id: number
spotify_uri: string
user_id: string | null
}
...
Og de ser ut til å bli tolket riktig:
Intellisense viser dette.
Og dette er min app.d.ts:
import { SupabaseClient, Session } from '@supabase/supabase-js';
import { Database } from '$lib/supabase/schema';
declare global {
namespace App {
interface Locals {
supabase: SupabaseClient<Database>;
getSession(): Promise<Session | null>;
}
interface PageData {
session: Session | null;
}
// interface Error {}
// interface Platform {}
}
}
Når jeg lette etter feilen fant jeg dette: https://github.com/sveltejs/language-tools/issues/732 og de snakker om en feil i Typescript, men jeg er helt nybegynner i Typescript, så jeg har ingen anelse om dette er relatert eller hva som foregår der.
Jeg forventet at SvelteKit/Typescript også skulle utlede typene for "data.playlist" fra skjemaet mitt innenfor #each-løkken, akkurat som det gjør innenfor skript-tagen. Ikke sikker på hvorfor det gir meg problemer. Takk for at du leser!
Svar #1
Det høres ut som supabase API-et muligens kan returnere null for data-egenskapen. Ikke sikker på om det gir mening når man velger en liste med objekter, men hvis typen sier det, trenger du en sjekk eller en ikke-null-assertion.
const { data: playlist } = ...
if (playlist == null)
throw ...; // or make it a `let` and assign an empty array?
// or
return {
user: session.user,
playlist: playlist!,
};
