Skip to content

Commit

Permalink
add a SvelteKit namespace for app-level types (#3569)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Feb 1, 2022
1 parent c1f5a13 commit d7e60f5
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 68 deletions.
15 changes: 15 additions & 0 deletions packages/kit/test/apps/basics/src/app.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
declare namespace SvelteKit {
interface Session {
answer: number;
calls: number;
}

interface Stuff {
message: string;
error: string;
page: string;
value: number;
x: string;
y: string;
}
}
10 changes: 8 additions & 2 deletions packages/kit/test/apps/basics/src/routes/store/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@
let calls = 0;
onMount(() => {
session.set(calls);
session.update(($session) => ({
...$session,
calls
}));
});
const unsubscribe = page.subscribe(() => {
calls++;
session.set(calls);
session.update(($session) => ({
...$session,
calls
}));
});
onDestroy(unsubscribe);
Expand Down
4 changes: 2 additions & 2 deletions packages/kit/test/apps/basics/src/routes/store/result.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
let calls = 0;
onMount(() => {
calls = get(session);
({ calls } = get(session));
});
</script>

<h1>Result</h1>
<h2>Calls: {calls}</h2>
<h2>Calls: {calls}</h2>
13 changes: 10 additions & 3 deletions packages/kit/types/ambient-modules.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
/* eslint-disable import/no-duplicates */

declare namespace SvelteKit {
interface Locals {}
interface Platform {}
interface Session {}
interface Stuff {}
}

declare module '$app/env' {
/**
* Whether or not app is in AMP mode.
Expand Down Expand Up @@ -106,10 +113,10 @@ declare module '$app/stores' {
* A convenience function around `getContext` that returns `{ navigating, page, session }`.
* Most of the time, you won't need to use it.
*/
export function getStores<Session = any>(): {
export function getStores(): {
navigating: typeof navigating;
page: typeof page;
session: Writable<Session>;
session: Writable<SvelteKit.Session>;
updated: typeof updated;
};
/**
Expand All @@ -132,7 +139,7 @@ declare module '$app/stores' {
* A writable store whose initial value is whatever was returned from `getSession`.
* It can be written to, but this will not cause changes to persist on the server — this is something you must implement yourself.
*/
export const session: Writable<any>;
export const session: Writable<SvelteKit.Session>;
/**
* A writable store indicating if the site was updated since the store was created.
* It can be written to when custom logic is required to detect updates.
Expand Down
3 changes: 0 additions & 3 deletions packages/kit/types/helper.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ export type ResponseHeaders = Record<string, string | string[]>;
type Only<T, U> = { [P in keyof T]: T[P] } & { [P in Exclude<keyof U, keyof T>]?: never };

export type Either<T, U> = Only<T, U> | Only<U, T>;
export type InferValue<T, Key extends keyof T, Default> = T extends Record<Key, infer Val>
? Val
: Default;
export type MaybePromise<T> = T | Promise<T>;
export type RecursiveRequired<T> = {
// Recursive implementation of TypeScript's Required utility type.
Expand Down
71 changes: 13 additions & 58 deletions packages/kit/types/page.d.ts
Original file line number Diff line number Diff line change
@@ -1,85 +1,40 @@
import { Fallthrough } from './endpoint';
import { Either, InferValue, MaybePromise } from './helper';
import { Either, MaybePromise } from './helper';

export interface LoadInput<
PageParams extends Record<string, string> = Record<string, string>,
Stuff extends Record<string, any> = Record<string, any>,
Session = any
> {
export interface LoadInput<Params = Record<string, string>> {
url: URL;
params: PageParams;
params: Params;
fetch(info: RequestInfo, init?: RequestInit): Promise<Response>;
session: Session;
stuff: Stuff;
session: SvelteKit.Session;
stuff: Partial<SvelteKit.Stuff>;
}

export interface ErrorLoadInput<
PageParams extends Record<string, string> = Record<string, string>,
Stuff extends Record<string, any> = Record<string, any>,
Session = any
> extends LoadInput<PageParams, Stuff, Session> {
export interface ErrorLoadInput<Params = Record<string, string>> extends LoadInput<Params> {
status?: number;
error?: Error;
}

export interface LoadOutput<
Props extends Record<string, any> = Record<string, any>,
Stuff extends Record<string, any> = Record<string, any>
> {
export interface LoadOutput<Props = Record<string, any>> {
status?: number;
error?: string | Error;
redirect?: string;
props?: Props;
stuff?: Stuff;
stuff?: Partial<SvelteKit.Stuff>;
maxage?: number;
}

interface LoadInputExtends {
stuff?: Record<string, any>;
pageParams?: Record<string, string>;
session?: any;
params?: Record<string, string>;
}

interface LoadOutputExtends {
stuff?: Record<string, any>;
props?: Record<string, any>;
}

export interface Load<
Input extends LoadInputExtends = Required<LoadInputExtends>,
Output extends LoadOutputExtends = Required<LoadOutputExtends>
> {
(
input: LoadInput<
InferValue<Input, 'pageParams', Record<string, string>>,
InferValue<Input, 'stuff', Record<string, any>>,
InferValue<Input, 'session', any>
>
): MaybePromise<
Either<
Fallthrough,
LoadOutput<
InferValue<Output, 'props', Record<string, any>>,
InferValue<Output, 'stuff', Record<string, any>>
>
>
>;
export interface Load<Params = Record<string, string>, Props = Record<string, any>> {
(input: LoadInput<Params>): MaybePromise<Either<Fallthrough, LoadOutput<Props>>>;
}

export interface ErrorLoad<
Input extends LoadInputExtends = Required<LoadInputExtends>,
Output extends LoadOutputExtends = Required<LoadOutputExtends>
> {
(
input: ErrorLoadInput<
InferValue<Input, 'pageParams', Record<string, string>>,
InferValue<Input, 'stuff', Record<string, any>>,
InferValue<Input, 'session', any>
>
): MaybePromise<
LoadOutput<
InferValue<Output, 'props', Record<string, any>>,
InferValue<Output, 'stuff', Record<string, any>>
>
>;
export interface ErrorLoad<Params = Record<string, string>, Props = Record<string, any>> {
(input: ErrorLoadInput<Params>): MaybePromise<LoadOutput<Props>>;
}

0 comments on commit d7e60f5

Please sign in to comment.