Skip to content

Conversation

@ivanhofer
Copy link
Contributor

@ivanhofer ivanhofer commented Mar 1, 2022

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • [] Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpx changeset and following the prompts. All changesets should be patch until SvelteKit 1.0

I want to be able to type the Params of a Load function that get's it's props from an Endpoint.
Currently the InputParams are always typed as Record<string, any>

Here is a simplified example:

/routes/[id].ts

import type { RequestHandler } from '@sveltejs/kit'

export type Product = {
   name: string,
   color: string,
}

type Params = { id: string}
type OutputType = Product

export const get: RequestHandler<Params, OutputType> = ({ params }) => {
   return {
      body: {
         name: `${params.id} product`,
         color: 'green',
      }
   }
}

/routes/[id].svelte

<script lang="ts" context="module">
   import type { Load } from '@sveltejs/kit'
   import type { get } from './[id]'

   type Params = { id: string }
   type InputProps = NonNullable<Awaited<ReturnType<typeof get>>['body']> // would be `Product`
   type OutputProps = Params & InputProps

   export const load: Load<Params, InputProps, OutputProps> = async ({
      params,
      props, // <= `InputProps`
      session,
   }) => {

      // ... some logic

      return {
         props: { // <= `OutputProps`
            product: props,
            id: params.id,
         },
      }
   }
</script>

This would be a breaking change

@changeset-bot
Copy link

changeset-bot bot commented Mar 1, 2022

🦋 Changeset detected

Latest commit: 18d8baf

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@benmccann
Copy link
Member

you'll need to run pnpm format because lint is currently failing

Comment on lines 118 to 125
export interface Load<
Params = Record<string, string>,
InputProps = Record<string, any>,
OutputProps = Record<string, any>
> {
(input: LoadInput<Params, InputProps>): MaybePromise<
Either<Fallthrough, LoadOutput<OutputProps>>
>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good if we could omit OutputProps in the common case where they're just being passed through, I think?

Suggested change
export interface Load<
Params = Record<string, string>,
InputProps = Record<string, any>,
OutputProps = Record<string, any>
> {
(input: LoadInput<Params, InputProps>): MaybePromise<
Either<Fallthrough, LoadOutput<OutputProps>>
>;
export interface Load<
Params extends Record<string, string> = Record<string, string>,
InputProps extends Record<string, any> = Record<string, any>,
OutputProps extends Record<string, any> = InputProps
> {
(input: LoadInput<Params, InputProps>): MaybePromise<
Either<Fallthrough, LoadOutput<OutputProps>>
>;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, I think this would make it a non-breaking change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would still be a breaking change.
Before this PR props (InputProps) could hold any Record, If someone would have set the Props before (OutputProps), this would now become the InputProps so this could throw some errors.
Here is an example

Before:

<script lang="ts" context="module">
   import type { Load } from '@sveltejs/kit'

   type Props = { value: string } 

   export const load: Load<any, Props> = async ({ props }) => {

      console.log(props.something) // valid

      return { /* ... */ }
   }
</script>

After:

<script lang="ts" context="module">
   import type { Load } from '@sveltejs/kit'

   type Props = { value: string } 

   export const load: Load<any, Props> = async ({ props }) => {

      console.log(props.something) // not valid anymore because only `value` is a known property

      return { /* ... */ }
   }
</script>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yep, gotcha. I've updated the changeset to reflect that. Breakingness aside, does this suggestion make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they make sense. I haven't spotted the missing extends in the generics because I was lazy and just copied the Props code from somewhere else ^^
Maybe it would make sense to take another look and update places where the extends is missing in the current code base? Should I take a look and include the fixes in this PR?

Also having the same InputProps and OutputProps could be a valid case 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's probably some other places that should use extends, but I'll merge this PR in the meantime anyway. Thank you!

Co-authored-by: Rich Harris <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants