Types
Edit this page on GitHub$app/formspermalink
ts
import {enhance ,applyAction } from '$app/forms';
SubmitFunctionpermalink
ts
typeSubmitFunction <Success extendsRecord <string, unknown> | undefined =Record <string, any>,Invalid extendsRecord <string, unknown> | undefined =Record <string, any>> = (input : {action :URL ;data :FormData ;form :HTMLFormElement ;controller :AbortController ;cancel (): void;| void| ((opts : {form :HTMLFormElement ;action :URL ;/*** Call this to get the default behavior of a form submission response.* @param options Set `reset: false` if you don't want the `<form>` values to be reset after a successful submission.*/update (options ?: {reset : boolean }):Promise <void>;}) => void)>;
@sveltejs/kitpermalink
The following can be imported from @sveltejs/kit
:
Actionpermalink
ts
interfaceAction <Params extendsPartial <Record <string, string>> =Partial <Record <string, string>>,OutputData extendsRecord <string, any> | void =Record <string, any> | void,RouteId extends string | null = string | null> {}
ActionResultpermalink
When calling a form action via fetch, the response will be one of these shapes.
ts
typeActionResult <Success extendsRecord <string, unknown> | undefined =Record <string, any>,Invalid extendsRecord <string, unknown> | undefined =Record <string, any>> =| {type : 'success';status : number;data ?:Success }| {type : 'invalid';status : number;data ?:Invalid }| {type : 'redirect';status : number;location : string }| {type : 'error';error : any };
Actionspermalink
ts
typeActions <Params extendsPartial <Record <string, string>> =Partial <Record <string, string>>,OutputData extendsRecord <string, any> | void =Record <string, any> | void,RouteId extends string | null = string | null
Adapterpermalink
ts
interfaceAdapter {name : string;}
AfterNavigatepermalink
The interface that corresponds to the afterNavigate
's input parameter.
ts
/*** The type of navigation:* - `enter`: The app has hydrated* - `link`: Navigation was triggered by a link click* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect* - `popstate`: Navigation was triggered by back/forward navigation*/willUnload : false;}
AwaitedActionspermalink
ts
typeAwaitedActions <T extendsRecord <string, (...args : any) => any>> = {[Key in keyofT ]:OptionalUnion <UnpackValidationError <Awaited <ReturnType <T [Key ]>>>>;}[keyofT ];
AwaitedPropertiespermalink
ts
typeAwaitedProperties <input extendsRecord <string, any> | void> =AwaitedPropertiesUnion <input > extendsRecord <string, any>?OptionalUnion <AwaitedPropertiesUnion <input >>:AwaitedPropertiesUnion <input >;
BeforeNavigatepermalink
The interface that corresponds to the beforeNavigate
's input parameter.
ts
/*** Call this to prevent the navigation from starting.*/cancel (): void;}
Builderpermalink
ts
interfaceBuilder {rimraf (dir : string): void;mkdirp (dir : string): void;config :ValidatedConfig ;/*** Create entry points that map to individual functions* @param fn A function that groups a set of routes into an entry point*/generateManifest (opts : {relativePath : string;format ?: 'esm' | 'cjs';}): string;getBuildDirectory (name : string): string;getClientDirectory (): string;getServerDirectory (): string;getStaticDirectory (): string;/** The application path including any configured base path */getAppPath (): string;/*** @param dest the destination folder to which files should be copied* @returns an array of paths corresponding to the files that have been created by the copy*/writeClient (dest : string): string[];/*** @param dest*/writePrerendered (dest : string,opts ?: {fallback ?: string;}): string[];/*** @param dest the destination folder to which files should be copied* @returns an array of paths corresponding to the files that have been created by the copy*/writeServer (dest : string): string[];/*** @param from the source file or folder* @param to the destination file or folder* @param opts.filter a function to determine whether a file or folder should be copied* @param opts.replace a map of strings to replace* @returns an array of paths corresponding to the files that have been created by the copy*/copy (from : string,to : string,opts ?: {filter ?(basename : string): boolean;replace ?:Record <string, string>;}): string[];/*** @param {string} directory Path to the directory containing the files to be compressed*/compress (directory : string):Promise <void>;}
Configpermalink
ts
interfaceConfig {compilerOptions ?:CompileOptions ;extensions ?: string[];package ?: {source ?: string;dir ?: string;emitTypes ?: boolean;exports ?(filepath : string): boolean;files ?(filepath : string): boolean;};preprocess ?: any;[key : string]: any;}
Cookiespermalink
ts
interfaceCookies {/*** Gets a cookie that was previously set with `cookies.set`, or from the request headers.*/get (name : string,opts ?: import('cookie').CookieParseOptions ): string | undefined;/*** Sets a cookie. This will add a `set-cookie` header to the response, but also make the cookie available via `cookies.get` during the current request.** The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`.** By default, the `path` of a cookie is the 'directory' of the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app.*/set (name : string,value : string,opts ?: import('cookie').CookieSerializeOptions ): void;/*** Deletes a cookie by setting its value to an empty string and setting the expiry date in the past.** By default, the `path` of a cookie is the 'directory' of the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app.*/delete (name : string,opts ?: import('cookie').CookieSerializeOptions ): void;/*** Serialize a cookie name-value pair into a Set-Cookie header string.** The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`.** By default, the `path` of a cookie is the current pathname. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app.** @param name the name for the cookie* @param value value to set the cookie to* @param options object containing serialization options*/serialize (name : string,value : string,opts ?: import('cookie').CookieSerializeOptions ): string;}
Handlepermalink
ts
interfaceHandle {(input : {}
HandleClientErrorpermalink
ts
interfaceHandleClientError {}
HandleFetchpermalink
ts
interfaceHandleFetch {(input : {request :Request ;fetch : typeoffetch ;}
HandleServerErrorpermalink
ts
interfaceHandleServerError {}
KitConfigpermalink
ts
interfaceKitConfig {alias ?:Record <string, string>;appDir ?: string;csp ?: {mode ?: 'hash' | 'nonce' | 'auto';};csrf ?: {checkOrigin ?: boolean;};env ?: {dir ?: string;publicPrefix ?: string;};moduleExtensions ?: string[];files ?: {assets ?: string;hooks ?: {client ?: string;server ?: string;};lib ?: string;params ?: string;routes ?: string;serviceWorker ?: string;appTemplate ?: string;errorTemplate ?: string;};inlineStyleThreshold ?: number;outDir ?: string;paths ?: {assets ?: string;base ?: string;};prerender ?: {concurrency ?: number;crawl ?: boolean;default ?: boolean;enabled ?: boolean;entries ?:Array <'*' | `/${string}`>;origin ?: string;};serviceWorker ?: {register ?: boolean;files ?(filepath : string): boolean;};version ?: {name ?: string;pollInterval ?: number;};}
Loadpermalink
The generic form of PageLoad
and LayoutLoad
. You should import those from ./$types
(see generated types)
rather than using Load
directly.
ts
interfaceLoad <Params extendsPartial <Record <string, string>> =Partial <Record <string, string>>,InputData extendsRecord <string, unknown> | null =Record <string, any> | null,ParentData extendsRecord <string, unknown> =Record <string, any>,OutputData extendsRecord <string, unknown> | void =Record <string,any> | void,RouteId extends string | null = string | null> {(}
LoadEventpermalink
ts
interfaceLoadEvent <Params extendsPartial <Record <string, string>> =Partial <Record <string, string>>,Data extendsRecord <string, unknown> | null =Record <string, any> | null,ParentData extendsRecord <string, unknown> =Record <string, any>,RouteId extends string | null = string | null/*** `fetch` is equivalent to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch), with a few additional features:** - it can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request* - it can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context)* - internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call* - during server-side rendering, the response will be captured and inlined into the rendered HTML. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](https://kit.svelte.dev/docs/hooks#server-hooks-handle)* - during hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request** > Cookies will only be passed through if the target host is the same as the SvelteKit application or a more specific subdomain of it.*/fetch : typeoffetch ;/*** Contains the data returned by the route's server `load` function (in `+layout.server.js` or `+page.server.js`), if any.*/data :Data ;/*** If you need to set headers for the response, you can do so using the this method. This is useful if you want the page to be cached, for example:** ```js* /// file: src/routes/blog/+page.js* export async function load({ fetch, setHeaders }) {* const url = `https://cms.example.com/articles.json`;* const response = await fetch(url);** setHeaders({* age: response.headers.get('age'),* 'cache-control': response.headers.get('cache-control')* });** return response.json();* }* ```** Setting the same header multiple times (even in separate `load` functions) is an error — you can only set a given header once.** You cannot add a `set-cookie` header with `setHeaders` — use the [`cookies`](https://kit.svelte.dev/docs/types#sveltejs-kit-cookies) API in a server-only `load` function instead.** `setHeaders` has no effect when a `load` function runs in the browser.*/setHeaders (headers :Record <string, string>): void;/*** `await parent()` returns data from parent `+layout.js` `load` functions.* Implicitly, a missing `+layout.js` is treated as a `({ data }) => data` function, meaning that it will return and forward data from parent `+layout.server.js` files.** Be careful not to introduce accidental waterfalls when using `await parent()`. If for example you only want to merge parent data into the returned output, call it _after_ fetching your other data.*/parent ():Promise <ParentData >;/*** This function declares that the `load` function has a _dependency_ on one or more URLs or custom identifiers, which can subsequently be used with [`invalidate()`](/docs/modules#$app-navigation-invalidate) to cause `load` to rerun.** Most of the time you won't need this, as `fetch` calls `depends` on your behalf — it's only necessary if you're using a custom API client that bypasses `fetch`.** URLs can be absolute or relative to the page being loaded, and must be [encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding).** Custom identifiers have to be prefixed with one or more lowercase letters followed by a colon to conform to the [URI specification](https://www.rfc-editor.org/rfc/rfc3986.html).** The following example shows how to use `depends` to register a dependency on a custom identifier, which is `invalidate`d after a button click, making the `load` function rerun.** ```js* /// file: src/routes/+page.js* let count = 0;* export async function load({ depends }) {* depends('increase:count');** return { count: count++ };* }* ```** ```html* /// file: src/routes/+page.svelte* <script>* import { invalidate } from '$app/navigation';** export let data;** const increase = async () => {* await invalidate('increase:count');* }* </script>** <p>{data.count}<p>* <button on:click={increase}>Increase Count</button>* ```*/depends (...deps : string[]): void;}
Navigationpermalink
ts
interfaceNavigation {/*** Where navigation was triggered from*//*** Where navigation is going to/has gone to*//*** The type of navigation:* - `leave`: The user is leaving the app by closing the tab or using the back/forward buttons to go to a different document* - `link`: Navigation was triggered by a link click* - `goto`: Navigation was triggered by a `goto(...)` call or a redirect* - `popstate`: Navigation was triggered by back/forward navigation*//*** Whether or not the navigation will result in the page being unloaded (i.e. not a client-side navigation)*/willUnload : boolean;/*** In case of a history back/forward navigation, the number of steps to go back/forward*/delta ?: number;}
NavigationEventpermalink
ts
interfaceNavigationEvent <Params extendsPartial <Record <string, string>> =Partial <Record <string, string>>,RouteId extends string | null = string | null> {/*** The parameters of the current page - e.g. for a route like `/blog/[slug]`, the `slug` parameter*/params :Params ;/*** Info about the current route*/route : {/*** The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `blog/[slug]`*/id :RouteId ;};/*** The URL of the current page*/url :URL ;}
NavigationTargetpermalink
ts
interfaceNavigationTarget {params :Record <string, string> | null;route : {id : string | null };url :URL ;}
NavigationTypepermalink
enter
: The app has hydratedleave
: The user is leaving the app by closing the tab or using the back/forward buttons to go to a different documentlink
: Navigation was triggered by a link clickgoto
: Navigation was triggered by agoto(...)
call or a redirectpopstate
: Navigation was triggered by back/forward navigation
ts
typeNavigationType = 'enter' | 'leave' | 'link' | 'goto' | 'popstate';
Pagepermalink
The shape of the $page
store
ts
interfacePage <Params extendsRecord <string, string> =Record <string, string>,RouteId extends string | null = string | null> {/*** The URL of the current page*/url :URL ;/*** The parameters of the current page - e.g. for a route like `/blog/[slug]`, the `slug` parameter*/params :Params ;/*** Info about the current route*/route : {/*** The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `blog/[slug]`*/id :RouteId ;};/*** Http status code of the current page*/status : number;/*** The error object of the current page, if any. Filled from the `handleError` hooks.*//*** The merged result of all data from all `load` functions on the current page. You can type a common denominator through `App.PageData`.*//*** Filled only after a form submission. See [form actions](https://kit.svelte.dev/docs/form-actions) for more info.*/form : any;}
ParamMatcherpermalink
ts
interfaceParamMatcher {(param : string): boolean;}
RequestEventpermalink
ts
interfaceRequestEvent <Params extendsPartial <Record <string, string>> =Partial <Record <string, string>>,RouteId extends string | null = string | null> {/*** Get or set cookies related to the current request*//*** `fetch` is equivalent to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch), with a few additional features:** - it can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request* - it can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context)* - internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call** > Cookies will only be passed through if the target host is the same as the SvelteKit application or a more specific subdomain of it.*/fetch : typeoffetch ;/*** The client's IP address, set by the adapter.*/getClientAddress (): string;/*** Contains custom data that was added to the request within the [`handle hook`](https://kit.svelte.dev/docs/hooks#server-hooks-handle).*//*** The parameters of the current page or endpoint - e.g. for a route like `/blog/[slug]`, the `slug` parameter*/params :Params ;/*** Additional data made available through the adapter.*//*** The original request object*/request :Request ;/*** Info about the current route*/route : {/*** The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `blog/[slug]`*/id :RouteId ;};/*** If you need to set headers for the response, you can do so using the this method. This is useful if you want the page to be cached, for example:** ```js* /// file: src/routes/blog/+page.js* export async function load({ fetch, setHeaders }) {* const url = `https://cms.example.com/articles.json`;* const response = await fetch(url);** setHeaders({* age: response.headers.get('age'),* 'cache-control': response.headers.get('cache-control')* });** return response.json();* }* ```** Setting the same header multiple times (even in separate `load` functions) is an error — you can only set a given header once.** You cannot add a `set-cookie` header with `setHeaders` — use the [`cookies`](https://kit.svelte.dev/docs/types#sveltejs-kit-cookies) API instead.*/setHeaders (headers :Record <string, string>): void;/*** The URL of the current page or endpoint*/url :URL ;}
RequestHandlerpermalink
A (event: RequestEvent) => Response
function exported from a +server.js
file that corresponds to an HTTP verb (GET
, PUT
, PATCH
, etc) and handles requests with that method.
It receives Params
as the first generic argument, which you can skip by using generated types instead.
ts
interfaceRequestHandler <Params extendsPartial <Record <string, string>> =Partial <Record <string, string>>,RouteId extends string | null = string | null> {}
ResolveOptionspermalink
ts
interfaceResolveOptions {transformPageChunk ?(input : {html : string;done : boolean;filterSerializedResponseHeaders ?(name : string,value : string): boolean;}
SSRManifestpermalink
ts
interfaceSSRManifest {appDir : string;appPath : string;assets :Set <string>;mimeTypes :Record <string, string>;/** private fields */_ : {entry : {file : string;imports : string[];stylesheets : string[];};nodes :SSRNodeLoader [];routes :SSRRoute [];};}
Serverpermalink
ts
classServer {}
ServerInitOptionspermalink
ts
interfaceServerInitOptions {env :Record <string, string>;}
ServerLoadpermalink
The generic form of PageServerLoad
and LayoutServerLoad
. You should import those from ./$types
(see generated types)
rather than using ServerLoad
directly.
ts
interfaceServerLoad <Params extendsPartial <Record <string, string>> =Partial <Record <string, string>>,ParentData extendsRecord <string, any> =Record <string, any>,OutputData extendsRecord <string, any> | void =Record <string, any> | void,RouteId extends string | null = string | null> {(}
ServerLoadEventpermalink
ts
interfaceServerLoadEvent <Params extendsPartial <Record <string, string>> =Partial <Record <string, string>>,ParentData extendsRecord <string, any> =Record <string, any>,RouteId extends string | null = string | null/*** `await parent()` returns data from parent `+layout.server.js` `load` functions.** Be careful not to introduce accidental waterfalls when using `await parent()`. If for example you only want to merge parent data into the returned output, call it _after_ fetching your other data.*/parent ():Promise <ParentData >;/*** This function declares that the `load` function has a _dependency_ on one or more URLs or custom identifiers, which can subsequently be used with [`invalidate()`](/docs/modules#$app-navigation-invalidate) to cause `load` to rerun.** Most of the time you won't need this, as `fetch` calls `depends` on your behalf — it's only necessary if you're using a custom API client that bypasses `fetch`.** URLs can be absolute or relative to the page being loaded, and must be [encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding).** Custom identifiers have to be prefixed with one or more lowercase letters followed by a colon to conform to the [URI specification](https://www.rfc-editor.org/rfc/rfc3986.html).** The following example shows how to use `depends` to register a dependency on a custom identifier, which is `invalidate`d after a button click, making the `load` function rerun.** ```js* /// file: src/routes/+page.js* let count = 0;* export async function load({ depends }) {* depends('increase:count');** return { count: count++ };* }* ```** ```html* /// file: src/routes/+page.svelte* <script>* import { invalidate } from '$app/navigation';** export let data;** const increase = async () => {* await invalidate('increase:count');* }* </script>** <p>{data.count}<p>* <button on:click={increase}>Increase Count</button>* ```*/depends (...deps : string[]): void;}
ValidationErrorpermalink
ts
interfaceValidationError <T extendsRecord <string, unknown> | undefined = undefinedstatus : number;data :T ;}
Additional typespermalink
The following are referenced by the public types documented above, but cannot be imported directly:
AdapterEntrypermalink
ts
interfaceAdapterEntry {/*** A string that uniquely identifies an HTTP service (e.g. serverless function) and is used for deduplication.* For example, `/foo/a-[b]` and `/foo/[c]` are different routes, but would both* be represented in a Netlify _redirects file as `/foo/:param`, so they share an ID*/id : string;/*** A function that compares the candidate route with the current route to determine* if it should be treated as a fallback for the current route. For example, `/foo/[c]`* is a fallback for `/foo/a-[b]`, and `/[...catchall]` is a fallback for all routes*//*** A function that is invoked once the entry has been created. This is where you* should write the function to the filesystem and generate redirect manifests.*/complete (entry : {generateManifest (opts : {relativePath : string;format ?: 'esm' | 'cjs';}): string;}
Csppermalink
ts
namespaceCsp {typeActionSource = 'strict-dynamic' | 'report-sample';typeBaseSource =| 'self'| 'unsafe-eval'| 'unsafe-hashes'| 'unsafe-inline'| 'wasm-unsafe-eval'| 'none';typeCryptoSource = `${'nonce' | 'sha256' | 'sha384' | 'sha512'}-${string}`;typeFrameSource =HostSource |SchemeSource | 'self' | 'none';typeHostNameScheme = `${string}.${string}` | 'localhost';typeHostSource = `${HostProtocolSchemes }${HostNameScheme }${PortScheme }`;typeHostProtocolSchemes = `${string}://` | '';typeHttpDelineator = '/' | '?' | '#' | '\\';typePortScheme = `:${number}` | '' | ':*';typeSchemeSource =| 'http:'| 'https:'| 'data:'| 'mediastream:'| 'blob:'| 'filesystem:';typeSource =HostSource |SchemeSource |CryptoSource |BaseSource ;typeSources =Source [];typeUriPath = `${HttpDelineator }${string}`;}
CspDirectivespermalink
ts
interfaceCspDirectives {sandbox ?:Array <| 'allow-downloads-without-user-activation'| 'allow-forms'| 'allow-modals'| 'allow-orientation-lock'| 'allow-pointer-lock'| 'allow-popups'| 'allow-popups-to-escape-sandbox'| 'allow-presentation'| 'allow-same-origin'| 'allow-scripts'| 'allow-storage-access-by-user-activation'| 'allow-top-navigation'| 'allow-top-navigation-by-user-activation'>;'frame-ancestors'?:Array <>;'report-to'?: string[];'require-trusted-types-for'?:Array <'script'>;'trusted-types'?:Array <'none' | 'allow-duplicates' | '*' | string>;'upgrade-insecure-requests'?: boolean;/** @deprecated */'require-sri-for'?:Array <'script' | 'style' | 'script style'>;/** @deprecated */'block-all-mixed-content'?: boolean;/** @deprecated */'plugin-types'?:Array <`${string}/${string}` | 'none'>;/** @deprecated */referrer ?:Array <| 'no-referrer'| 'no-referrer-when-downgrade'| 'origin'| 'origin-when-cross-origin'| 'same-origin'| 'strict-origin'| 'strict-origin-when-cross-origin'| 'unsafe-url'| 'none'>;}
HttpMethodpermalink
ts
typeHttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
Loggerpermalink
ts
interfaceLogger {(msg : string): void;success (msg : string): void;error (msg : string): void;warn (msg : string): void;minor (msg : string): void;info (msg : string): void;}
MaybePromisepermalink
ts
typeMaybePromise <T > =T |Promise <T >;
PrerenderHttpErrorHandlerpermalink
ts
interfacePrerenderHttpErrorHandler {(details : {status : number;path : string;referrer : string | null;referenceType : 'linked' | 'fetched';}): void;}
PrerenderHttpErrorHandlerValuepermalink
ts
typePrerenderHttpErrorHandlerValue =| 'fail'| 'warn'| 'ignore'
PrerenderMappermalink
ts
PrerenderMissingIdHandlerpermalink
ts
interfacePrerenderMissingIdHandler {(details : {path : string;id : string;referrers : string[] }): void;}
PrerenderMissingIdHandlerValuepermalink
ts
typePrerenderMissingIdHandlerValue =| 'fail'| 'warn'| 'ignore'
PrerenderOptionpermalink
ts
typePrerenderOption = boolean | 'auto';
Prerenderedpermalink
ts
interfacePrerendered {pages :Map <string,{/** The location of the .html file relative to the output directory */file : string;}>;assets :Map <string,{/** The MIME type of the asset */type : string;}>;redirects :Map <string,{status : number;location : string;}>;/** An array of prerendered paths (without trailing slashes, regardless of the trailingSlash config) */paths : string[];}
RequestOptionspermalink
ts
interfaceRequestOptions {getClientAddress (): string;}
RouteDefinitionpermalink
ts
interfaceRouteDefinition {id : string;pattern :RegExp ;}
RouteSegmentpermalink
ts
interfaceRouteSegment {content : string;dynamic : boolean;rest : boolean;}
TrailingSlashpermalink
ts
typeTrailingSlash = 'never' | 'always' | 'ignore';
UniqueInterfacepermalink
ts
interfaceUniqueInterface {readonly [uniqueSymbol ]: unknown;}
Apppermalink
It's possible to tell SvelteKit how to type objects inside your app by declaring the App
namespace. By default, a new project will have a file called src/app.d.ts
containing the following:
ts
By populating these interfaces, you will gain type safety when using event.locals
, event.platform
, and data
from load
functions.
Note that since it's an ambient declaration file, you have to be careful when using import
statements. Once you add an import
at the top level, the declaration file is no longer considered ambient and you lose access to these typings in other files.
To avoid this, either use the import(...)
function:
ts
user : import('$lib/types').User ;}
Or wrap the namespace with declare global
:
ts
import {User } from '$lib/types';declareglobal {namespaceApp {user :User ;}// ...}}
Errorpermalink
Defines the common shape of expected and unexpected errors. Expected errors are thrown using the error
function. Unexpected errors are handled by the handleError
hooks which should return this shape.
ts
interfaceError {message : string;}
Localspermalink
The interface that defines event.locals
, which can be accessed in hooks (handle
, and handleError
), server-only load
functions, and +server.js
files.
ts
interfaceLocals {}
PageDatapermalink
Defines the common shape of the $page.data store - that is, the data that is shared between all pages.
The Load
and ServerLoad
functions in ./$types
will be narrowed accordingly.
Use optional properties for data that is only present on specific pages. Do not add an index signature ([key: string]: any
).
ts
interfacePageData {}
Platformpermalink
If your adapter provides platform-specific context via event.platform
, you can specify it here.
ts
interfacePlatform {}
Generated typespermalink
The RequestHandler
and Load
types both accept a Params
argument allowing you to type the params
object. For example this endpoint expects foo
, bar
and baz
params:
src/routes/[foo]/[bar]/[baz]/+page.server.js
ts
* foo: string;* bar: string;* baz: string* }>} */export async functionA function whose declared type is neither 'void' nor 'any' must return a value.2355A function whose declared type is neither 'void' nor 'any' must return a value.({ GET params }) {// ...}
src/routes/[foo]/[bar]/[baz]/+page.server.ts
ts
Type '({ params }: RequestEvent<Partial<Record<string, string>>, string | null>) => Promise<void>' is not assignable to type 'RequestHandler<Partial<Record<string, string>>, string | null>'. Type 'Promise<void>' is not assignable to type 'MaybePromise<Response>'. Type 'Promise<void>' is not assignable to type 'Promise<Response>'. Type 'void' is not assignable to type 'Response'.2322Type '({ params }: RequestEvent<Partial<Record<string, string>>, string | null>) => Promise<void>' is not assignable to type 'RequestHandler<Partial<Record<string, string>>, string | null>'. Type 'Promise<void>' is not assignable to type 'MaybePromise<Response>'. Type 'Promise<void>' is not assignable to type 'Promise<Response>'. Type 'void' is not assignable to type 'Response'.// ...}
Needless to say, this is cumbersome to write out, and less portable (if you were to rename the [foo]
directory to [qux]
, the type would no longer reflect reality).
To solve this problem, SvelteKit generates .d.ts
files for each of your endpoints and pages:
.svelte-kit/types/src/routes/[foo]/[bar]/[baz]/$types.d.ts
ts
import type * asKit from '@sveltejs/kit';typeRouteParams = {foo : string;bar : string;baz : string;}export typePageServerLoad =Kit .ServerLoad <RouteParams >;export typePageLoad =Kit .Load <RouteParams >;
These files can be imported into your endpoints and pages as siblings, thanks to the rootDirs
option in your TypeScript configuration:
src/routes/[foo]/[bar]/[baz]/+page.server.js
ts
/** @type {import('./$types').PageServerLoad} */export async functionGET ({params }) {// ...}
src/routes/[foo]/[bar]/[baz]/+page.server.ts
ts
import type {PageServerLoad } from './$types';export constGET :PageServerLoad = async ({params }) => {// ...}
src/routes/[foo]/[bar]/[baz]/+page.js
ts
/** @type {import('./$types').PageLoad} */export async functionload ({params ,fetch }) {// ...}
src/routes/[foo]/[bar]/[baz]/+page.ts
ts
import type {PageLoad } from './$types';export constload :PageLoad = async ({params ,fetch }) => {// ...}
For this to work, your own
tsconfig.json
orjsconfig.json
should extend from the generated.svelte-kit/tsconfig.json
(where.svelte-kit
is youroutDir
):{ "extends": "./.svelte-kit/tsconfig.json" }
Default tsconfig.jsonpermalink
The generated .svelte-kit/tsconfig.json
file contains a mixture of options. Some are generated programmatically based on your project configuration, and should generally not be overridden without good reason:
.svelte-kit/tsconfig.json
{
"compilerOptions": {
"baseUrl": "..",
"paths": {
"$lib": "src/lib",
"$lib/*": "src/lib/*"
},
"rootDirs": ["..", "./types"]
},
"include": ["../src/**/*.js", "../src/**/*.ts", "../src/**/*.svelte"],
"exclude": ["../node_modules/**", "./**"]
}
Others are required for SvelteKit to work properly, and should also be left untouched unless you know what you're doing:
.svelte-kit/tsconfig.json
{
"compilerOptions": {
// this ensures that types are explicitly
// imported with `import type`, which is
// necessary as svelte-preprocess cannot
// otherwise compile components correctly
"importsNotUsedAsValues": "error",
// Vite compiles one TypeScript module
// at a time, rather than compiling
// the entire module graph
"isolatedModules": true,
// TypeScript cannot 'see' when you
// use an imported value in your
// markup, so we need this
"preserveValueImports": true,
// This ensures both `vite build`
// and `svelte-package` work correctly
"lib": ["esnext", "DOM", "DOM.Iterable"],
"moduleResolution": "node",
"module": "esnext",
"target": "esnext"
}
}