Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat : [Svelte5] Generate a PageProps into $types #12726

Closed
adiguba opened this issue Sep 27, 2024 · 4 comments · Fixed by #13308
Closed

Feat : [Svelte5] Generate a PageProps into $types #12726

adiguba opened this issue Sep 27, 2024 · 4 comments · Fixed by #13308
Labels

Comments

@adiguba
Copy link

adiguba commented Sep 27, 2024

Describe the problem

Sveltekit generate a type PageData for each +page.svelte, which allows to properly type the data prop :

<!-- Svelte 4 -->
<script lang="ts">
    import type { PageData } from './$types';
    
    export let data: PageData;
</script>

It's fine with Svelte 4, but with the new syntax in Svelte 5 we have to define an additional type for the $props runes :

<!-- Svelte 5 -->
<script lang="ts">
    import type { PageData } from './$types';

    type Props = {
        data: PageData;
    }
    
    let {
        data
    } : Props = $props();
</script>

Describe the proposed solution

The generated $types should include a new type PageProps, in the following manner :

export type PageProps = {
    data: PageData;
}

Which would allow us to write directly :

<!-- Svelte 5 -->
<script lang="ts">
    import type { PageProps } from './$types';

    let {
        data
    } : PageProps = $props();
</script>

Alternatives considered

Rewrite the $props() type on every page...

Importance

nice to have

Additional Information

No response

@Zinnavoy
Copy link

Zinnavoy commented Nov 1, 2024

I just faced this issue and it is indeed pretty ugly to have to do this. It's similar for component props, for example for a Shadcn UI Form with Superforms, you end up with something like this for a simple form component:

  import { type SuperValidated, type Infer,  superForm } from "sveltekit-superforms";
  import { zodClient } from "sveltekit-superforms/adapters";

  import * as Form from "$lib/components/ui/form/index.js";
  import { Input } from "$lib/components/ui/input/index.js";

  import { formSchema, type FormSchema } from "./schema";

  interface FormProps {
    data: SuperValidated<Infer<FormSchema>>;
  }

  const { data }: FormProps = $props();

  const form = superForm(data, {
    validators: zodClient(formSchema),
  });

  const { form: formData, enhance } = form;

@MathiasWP
Copy link
Contributor

What about making like this?

// +page.ts
export const load = () => {
	return {
		framework: "svelte",
		version: 5
	}
}
<script lang="ts">
// +page.svelte
import { PageProps } from './$types';

let { framework, version }: PageProps = $props()
</script>

A +page.svelte file cannot get its props from anything other than the load method, right? So why have the extra "data" variable wrapping? I see why it was needed with Svelte 4, but it feels unnecessary with Svelte 5.

@mpost
Copy link

mpost commented Nov 27, 2024

A possible solution/workaround would be to export the type of the load() function and use for the data type:

+page.server.ts

  export type LoadReturnType = Awaited<ReturnType<typeof load>>

+page.svelte

  import type { LoadReturnType } from './+page.server'

  let { data }: { data: LoadReturnType } = $props()

In the server side you would likely want to combine the return type with the parent() return type of the parent layout.

@rChaoz
Copy link
Contributor

rChaoz commented Jan 14, 2025

Since the other PR went kind of stale, opened #13308 to address the comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
6 participants