svelte - Typescript-fout met SvelteKit en Supabase-gegevens ophalen (Type 'null' kan niet worden toegewezen aan type 'ArrayLike')
Ik heb een SvelteKit-project opgezet dat authenticatie met Supabase gebruikt. Ik heb hiervoor deze gids gebruikt. De authenticatie en het ophalen van gegevens werkt tot nu toe prima. Eigenlijk werkt alles in de app zelf zoals verwacht. Ik krijg alleen een vervelende Typescript-fout die ik niet kan verwijderen.
Ik haal de gegevens op in dit bestand:
// <!-- 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
};
};
En het bijbehorende svelte-bestand om het weer te geven:
<!-- 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>
Dit zijn nu de fouten die ik krijg:
'pl' is of type 'unknown'.En
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>'.
Maar, zoals ik zei, wordt op de webpagina alles weergegeven zoals verwacht en krijg ik geen andere fouten, het lijkt alleen dat Typescript niet tevreden is. Wat ook vreemd is, is dat het data.user.email-gedoe helemaal geen fouten geeft.
De automatisch gegenereerde types van Supabase zien er zo uit:
// $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
}
...
En ze lijken correct te worden afgeleid:
Intellisense toont dit.
En dit is mijn 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 {}
}
}
Toen ik naar de fout zocht, vond ik dit: https://github.com/sveltejs/language-tools/issues/732 en ze praten over een bug in Typescript, maar ik ben een totale beginner in Typescript, dus ik heb geen idee of dit gerelateerd is of wat daar aan de hand is.
Ik verwachtte dat SvelteKit/Typescript de types voor "data.playlist" ook zou afleiden van mijn schema binnen de #each-lus, net zoals het dat doet binnen het script-tag. Niet zeker waarom het me problemen geeft. Bedankt voor het lezen!
Antwoord #1
Het lijkt erop dat de Supabase API mogelijk null kan teruggeven voor de data-eigenschap. Niet zeker of dat logisch is bij het selecteren van een lijst met objecten, maar als het type dat aangeeft, heb je een guard of een not-null-assertie nodig.
const { data: playlist } = ...
if (playlist == null)
throw ...; // or make it a `let` and assign an empty array?
// or
return {
user: session.user,
playlist: playlist!,
};
