Typescript error with SvelteKit and Supabase data fetching (Type 'null' is not assignable to type 'ArrayLike<unknown>')

huangapple go评论85阅读模式
英文:

Typescript error with SvelteKit and Supabase data fetching (Type 'null' is not assignable to type 'ArrayLike<unknown>')

问题

以下是您提供的代码的翻译部分:

// &lt;!-- routes/playlists/+page.ts --&gt;

import type { PageLoad } from &#39;./$types&#39;;
import { redirect } from &#39;@sveltejs/kit&#39;;

export const load: PageLoad = async ({ parent }) =&gt; {
    const { supabase, session } = await parent();
    if (!session) {
        throw redirect(303, &#39;/&#39;);
    }

    const { data: playlist } = await supabase.from(&#39;playlist&#39;).select(&#39;*&#39;);

    return {
        user: session.user,
        playlist
    };
};
&lt;!-- routes/playlists/+page.svelte --&gt;

&lt;script lang=&quot;ts&quot;&gt;
	import type { PageData } from &#39;./$types&#39;;
	import { json } from &#39;@sveltejs/kit&#39;;
	export let data: PageData;
&lt;/script&gt;

&lt;main&gt;
	&lt;div&gt;{data.user.email}&lt;/div&gt; &lt;!-- This works fine! --&gt;

	&lt;ul&gt;
		{#each data.playlist as pl}  &lt;!-- Typescript complains about this --&gt;
			&lt;li&gt;
				{pl.spotify_uri}  &lt;!-- and this --&gt;
			&lt;/li&gt;
		{/each}
	&lt;/ul&gt;
&lt;/main&gt;
// $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 &#39;@supabase/supabase-js&#39;;
import { Database } from &#39;$lib/supabase/schema&#39;;

declare global {
	namespace App {
		interface Locals {
			supabase: SupabaseClient&lt;Database&gt;;
			getSession(): Promise&lt;Session | null&gt;;
		}
		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:

// &lt;!-- routes/playlists/+page.ts --&gt;

import type { PageLoad } from &#39;./$types&#39;;
import { redirect } from &#39;@sveltejs/kit&#39;;

export const load: PageLoad = async ({ parent }) =&gt; {
    const { supabase, session } = await parent();
    if (!session) {
        throw redirect(303, &#39;/&#39;);
    }

    const { data: playlist } = await supabase.from(&#39;playlist&#39;).select(&#39;*&#39;);

    return {
        user: session.user,
        playlist
    };
};

And the corresponding svelte file to display it:


&lt;!-- routes/playlists/+page.svelte --&gt;

&lt;script lang=&quot;ts&quot;&gt;
	import type { PageData } from &#39;./$types&#39;;
	import { json } from &#39;@sveltejs/kit&#39;;
	export let data: PageData;
&lt;/script&gt;

&lt;main&gt;
	&lt;div&gt;{data.user.email}&lt;/div&gt; &lt;!-- This works fine! --&gt;

	&lt;ul&gt;
		{#each data.playlist as pl}  &lt;!-- Typescript complains about this --&gt;
			&lt;li&gt;
				{pl.spotify_uri}  &lt;!-- and this --&gt;
			&lt;/li&gt;
		{/each}
	&lt;/ul&gt;
&lt;/main&gt;

Now these are the errors I’m getting:

&#39;pl&#39; is of type &#39;unknown&#39;.

And

Argument of type &#39;{ 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&#39; 
is not assignable to parameter of type &#39;ArrayLike&lt;unknown&gt;&#39;.

Type &#39;null&#39; is not assignable to type &#39;ArrayLike&lt;unknown&gt;&#39;.

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:

Intellisense shows this.

And this is my app.d.ts:

import { SupabaseClient, Session } from &#39;@supabase/supabase-js&#39;;
import { Database } from &#39;$lib/supabase/schema&#39;;

declare global {
	namespace App {
		interface Locals {
			supabase: SupabaseClient&lt;Database&gt;;
			getSession(): Promise&lt;Session | null&gt;;
		}
		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!,
};

huangapple
  • 本文由 发表于 2023年5月25日 09:09:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76328274.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定