英文:
Typescript error with SvelteKit and Supabase data fetching (Type 'null' is not assignable to type 'ArrayLike<unknown>')
问题
以下是您提供的代码的翻译部分:
// <!-- 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
};
};
<!-- 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>
// $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
}
}
}
}
}
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 {}
}
}
希望这能帮助您理解问题并找到解决方案。如果您需要进一步的帮助,请告诉我。
英文:
I have a SvelteKit project set up which authenticates with supabase. I used this guide for that. The authentication and data fetching works fine so far. Actually, in terms of the app itself, everything works as expected. I’m just getting a nasty Typescript error which I can’t get rid of.
I’m fetching the data in this file:
// <!-- 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
};
};
And the corresponding svelte file to display it:
<!-- 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>
Now these are the errors I’m getting:
'pl' is of type 'unknown'.
And
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>'.
But, as I said, on the webpage everything is displayed just as expected & I’m getting no other errors, it just seems that Typescript isn’t happy. What’s also weird is that the data.user.email thing throws no errors at all.
The auto-generated types from supabase look like this:
// $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
}
...
And they seem to get inferred correctly:
And this is my 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 {}
}
}
When searching for the error I found this: https://github.com/sveltejs/language-tools/issues/732 and they talk about some bug in Typescript, but I’m a total Typescript beginner so I have no idea if this is related or what’s going on there.
I expected SvelteKit/Typescript to infer the types for "data.playlist" from my schema within the #each loop as well, just like it’s doing within the script tag. Not sure why it’s giving me trouble. Thanks for reading!
答案1
得分: 0
听起来,supabase API 可能会在 data
属性上返回 null
。虽然在选择对象列表时是否有意义还不确定,但如果类型指明如此,你需要添加一个保护或非空断言。
const { data: playlist } = ...
if (playlist == null)
throw ...; // 或者将其声明为 `let` 并分配一个空数组?
// 或者
return {
user: session.user,
playlist: playlist!,
};
英文:
Sounds like the supabase API can possibly return null
for the data
property. Not sure if that makes sense when selecting a list of objects, though, but if the type says so, you need a guard or not-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!,
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论