sveltejs / kit

web development, streamlined
https://svelte.dev/docs/kit
MIT License
18.77k stars 1.96k forks source link

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

Open adiguba opened 2 months ago

adiguba commented 2 months ago

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 commented 3 weeks ago

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 commented 1 week ago

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.