最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

typescript - Typing layout data in nested routes - Stack Overflow

programmeradmin0浏览0评论

In SvelteKit, I have a structure like this:

  • /accounts/[id]/+layout.server.svelte
  • /accounts/[id]/+layout.svelte
  • /accounts/[id]/view/+page.svelte
  • /accounts/[id]/edit/+page.svelte
  • /accounts/[id]/delete/+page.svelte

In the load() function in +layout.server.svelte I return the account with the given id, or null if no account with the given id exists. I.e., the return type is:

{
    account: Account | null
}

In +layout.svelte, I only show the nested route if an account with the given id exists:

{#if data.account}
    <slot />
{:else}
    <p>No account with the given id exists!</>
{/if}

But in all the nested +page.svelte files, the type of the data props is still:

{
    account: Account | null
}

But given the {#if} check I have in +layout.svelte, I know that account will never be null in the +page.svelte files. Everything works great, but TypeScript complains that account can be null each time I use it in the +page.svelte files, and that makes it very hard to read the code and see any potential real error.

What is the best/simplest workaround for this?

In SvelteKit, I have a structure like this:

  • /accounts/[id]/+layout.server.svelte
  • /accounts/[id]/+layout.svelte
  • /accounts/[id]/view/+page.svelte
  • /accounts/[id]/edit/+page.svelte
  • /accounts/[id]/delete/+page.svelte

In the load() function in +layout.server.svelte I return the account with the given id, or null if no account with the given id exists. I.e., the return type is:

{
    account: Account | null
}

In +layout.svelte, I only show the nested route if an account with the given id exists:

{#if data.account}
    <slot />
{:else}
    <p>No account with the given id exists!</>
{/if}

But in all the nested +page.svelte files, the type of the data props is still:

{
    account: Account | null
}

But given the {#if} check I have in +layout.svelte, I know that account will never be null in the +page.svelte files. Everything works great, but TypeScript complains that account can be null each time I use it in the +page.svelte files, and that makes it very hard to read the code and see any potential real error.

What is the best/simplest workaround for this?

Share Improve this question asked Nov 20, 2024 at 9:58 Peppe L-GPeppe L-G 8,3602 gold badges29 silver badges55 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I would try to use +error pages for that instead.

I.e. if the account is not found, use the error function to cause an exception that will show the error page, that way the data can be non-nullable.

// in load
if (account == null)
  error(404, { message: 'No account with the given id exists!' });

Note that if you throw errors in a layout's load function, the +error.svelte from the directory above will be shown, unfortunately. So you need an /accounts/+error.svelte page to handle this.

<!-- src/routes/accounts/+error.svelte -->
<script lang="ts">
  import { page } from '$app/stores';
</script>

<p>{$page.error?.message ?? 'Unknown error'}</p>

If [id] is the only meaningful sub-route that should not be a problem, otherwise you might have to add some metadata to the error to differentiate them if the message alone is not enough, e.g.

// in load
const body = {
  message: 'No account with the given id exists!',
  type: 'account-not-found',
};
error(404, body);
<!-- +error.svelte -->
<script lang="ts">
  import { page } from '$app/stores';

  $: error = $page.error as { type: string, message: string } | null;
</script>

{#if error?.type == 'account-not-found'}
  <!-- Specific error handling here -->
  <p>{error.message}</p>
{:else}
  <p>Unknown error</p>
{/if}
发布评论

评论列表(0)

  1. 暂无评论