svelte - Typescript hiba SvelteKit és Supabase adatlekérdezés közben (A 'null' típus nem rendelhető az 'ArrayLike' típushoz)
Van egy SvelteKit projektem, amely a supabase-szal autentikál. Ehhez a cikkhez használtam ezt az útmutatót. Az autentikáció és az adatok lekérése eddig jól működik. Valójában az alkalmazás maga szempontjából minden a vártnak megfelelően működik. Csak egy csúnya Typescript hibát kapok, amelytől nem tudok megszabadulni.
A fájlban lévő adatokat töltöm be:
// <!-- 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
};
};
És a megfelelő svelte fájl annak megjelenítéséhez:
<!-- 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>
Most ezek azok a hibák, amiket kapok:
'pl' is of type 'unknown'.És
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>'.
De, ahogy mondtam, a weboldalon minden pontosan a vártnak megfelelően jelenik meg, és nincs más hibám, úgy tűnik, a Typescript egyszerűen nincs elégedve. Ami különös, hogy a data.user.email dolog egyáltalán nem dob hibát.
A Supabase által automatikusan generált típusok így néznek ki:
// $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
}
...
És úgy tűnik, hogy helyesen kerülnek levezetésre:
Az Intellisense ezt mutatja.
És ez az én app.d.ts fájlom:
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 {}
}
}
Amikor az hibát kerestem, ezt találtam: https://github.com/sveltejs/language-tools/issues/732, és beszélnek valami hibáról a Typescript-ben, de én teljesen kezdő vagyok a Typescript-ben, szóval fogalmam sincs, hogy ez kapcsolódik-e vagy mi folyik ott.
Azt vártam, hogy a SvelteKit/Typescript a #each ciklusban is kikövetkezteti a típusokat a "data.playlist"-ből a sémám alapján, ugyanúgy, ahogy a script címkén belül teszi. Nem vagyok biztos benne, miért okoz ez nekem problémát. Köszönöm, hogy elolvastad!
Válasz #1
Úgy tűnik, hogy a supabase API esetleg visszaadhat null-t a data tulajdonságnál. Nem vagyok biztos benne, hogy ennek van értelme, amikor egy objektumok listáját választjuk, de ha a típus így jelzi, szükséged van egy ellenőrzésre vagy nem-null állításra.
const { data: playlist } = ...
if (playlist == null)
throw ...; // or make it a `let` and assign an empty array?
// or
return {
user: session.user,
playlist: playlist!,
};
