Search code examples
typescriptsveltekitjsdoc

How does @type import('./$types') Comment Syntax work in SvelteKit?


I'm currently learning SvelteKit and came across some code that I don't get the syntax of.

In +page.server.ts I don't understand this syntax:

/** @type {import('./$types').PageServerLoad} */

To my untrained eye this looks like it's just commented out but the /** */ is doing something that ensures it works. No idea.


Solution

  • SvelteKit generates a .svelte-kit directory whenever you run a dev or build command. In this directory are many files that are generated for prerendering and also type definitions. These definitions give you autocompletion and error checking in text editors that support TypeScript.

    $types is an alias to the respective $types.d.ts type declaration file in the .svelte-kit/types/src/routes/... folder.

    Shows the files and folders in the .svelte-kit directory

    These types can be imported, so that your text editor can understand the types of your load function. The types can be imported in two ways:

    A. JSDoc comment + TypeScript-specific import types

    Let's say you have a page.server.ts file in the file path src/routes/blog/[slug]. This gives you autocompletion and type checking on the params object as seen below.

    /** @type {import('./$types').PageServerLoad} */
    export const load = async ({ params }) => {
      params.slug // autocompletes, no error
      params.snail 
          // ^^^^^ error: Property 'snail' does not 
          //       exist on type 'RouteParams'
    }
    

    This looks like regular JSDoc comment but the import() function is TypeScript-specific. More about it in the TypeScript Handbook (thanks to jonrsharpe for mentioning the link).

    JSDoc comments might be limited. It seems to support annotating modules.

    B. TypeScript type annotation

    If you are using TypeScript you can also use another syntax:

    import type { PageServerLoad } from './$types';
    
    export const load: PageServerLoad = async ({ params }) => {
      // ... 
    }
    

    Further reading (about how TypeScript integrates into text editors/IDEs):