Sapper: [TypeScript] Provide typings for preload function (especially `this` context)

Created on 31 Aug 2020  路  5Comments  路  Source: sveltejs/sapper

Is your feature request related to a problem? Please describe.
People are having a hard time trying to figure out how to type the preload function correctly, especially when using this (like in this.fetch(...)). It is possible to do by adding a this type to the preload function, but this may not be widely known.

Describe the solution you'd like
Provide typings for the preload function for people to import.

<script context="module">
    import type { PreloadContext, PreloadPage, PreloadSession } from "@sapper/preload";

    export async function preload(this: PreloadContext, page: PreloadPage, session: PreloadSession) {
       ...
       this.fetch(...) // <-- works without type errors
    }
</script>

Also note this in the official docs so it's easy to discover how to do this.

(I'm happy to help / provide a PR if you give me pointers on where to add this)

Describe alternatives you've considered
Don't provide the functions through some this context, but through a third parameter of the function: export async function preload(page, session, {fetch, error, redirect}) { ...}. This would be a breaking change of course.

Additional context
I also started thinking about adding something to the language-server but ditched that because you can type it yourself, and because the this-context could be enhanced by the user in the future (if I'm interpreting @benmccann correctly).

All 5 comments

Ah, I forgot you could do that with this. (I actually just learned that in the past week or two).

I'd be happy for a PR implementing this!

We added some types in https://github.com/sveltejs/sapper/pull/1402. The preload stuff was not there

The preload_context is defined / used without type definitions in:
runtime/src/server/middleware/get_page_handler.ts
runtime/src/app/app.ts

One thing I kind of punted on with the initial type defs is figuring out how to share types between our internal code and what the user uses. I'm not sure whether that'd be hard or not as I hadn't gotten much time to spend on the problem. It's a little unusual because Sapper has a copy_runtime method that copies the types to a new location when the user builds their app.

(and yes, you interpreted me correctly - there's a desire to allow the this context to be enhanced by the user)

Maybe also export a function type so it could be easier to type

<script context="module">
  export const preload: SapperPreload = function preload () {  }
</script>

or a dummy helper function with a typed callback parameter but does nothing in the runtime

function sapper_preload(preload: SapperPreload) {
  return preload
}

How does one use the types defined in #1468? The documented method doesn't appear to work for a fresh sapper-template. Using it as written results in Cannot use namespace 'Preload' as a type. and switching the Preload type assignment to typeof Preload (which feels wrong to me anyway, but at least compiles), results in the arguments still having any type.

This was fixed in #1598 but is not yet released.

This was fixed in #1598 but is not yet released.

The problem is fixed after upgrading sapper to the latest version (0.29.x).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

keyvan-m-sadeghi picture keyvan-m-sadeghi  路  4Comments

BMorearty picture BMorearty  路  3Comments

Rich-Harris picture Rich-Harris  路  3Comments

antony picture antony  路  3Comments

Rich-Harris picture Rich-Harris  路  3Comments