Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 6 additions & 15 deletions documentation/docs/06-runtime/02-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,27 +83,18 @@ Svelte will warn you if you get it wrong.

## Type-safe context

A useful pattern is to wrap the calls to `setContext` and `getContext` inside helper functions that let you preserve type safety:
As an alternative to using `setContext` and `getContext` directly, you can use them via `createContext`. This gives you type safety and makes it unnecessary to use a key:

```js
/// file: context.js
```ts
/// file: context.ts
// @filename: ambient.d.ts
interface User {}

// @filename: index.js
// @filename: index.ts
// ---cut---
import { getContext, setContext } from 'svelte';

const key = {};

/** @param {User} user */
export function setUserContext(user) {
setContext(key, user);
}
import { createContext } from 'svelte';

export function getUserContext() {
return /** @type {User} */ (getContext(key));
}
export const [getUserContext, setUserContext] = createContext<User>();

This comment was marked as resolved.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not too worried about the JSDoc experience tbh. If people care about type safety, and they're building an app rather than a library, they're almost certainly using .ts. And if they don't then they can do the ReturnType thing, it's fine

```

## Replacing global state
Expand Down
8 changes: 8 additions & 0 deletions packages/svelte/src/internal/client/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,12 @@ export function set_dev_current_component_function(fn) {

/**
* Returns a `[get, set]` pair of functions for working with context in a type-safe way.
*
* `get` will throw an error if no parent component called `set`.
*
* @template T
* @returns {[() => T, (context: T) => T]}
* @since 5.40.0
*/
export function createContext() {
const key = {};
Expand All @@ -93,6 +97,8 @@ export function createContext() {
* Retrieves the context that belongs to the closest parent component with the specified `key`.
* Must be called during component initialisation.
*
* [`createContext`](https://svelte.dev/docs/svelte/svelte#createContext) is a type-safe alternative.
*
* @template T
* @param {any} key
* @returns {T}
Expand All @@ -110,6 +116,8 @@ export function getContext(key) {
*
* Like lifecycle functions, this must be called during component initialisation.
*
* [`createContext`](https://svelte.dev/docs/svelte/svelte#createContext) is a type-safe alternative.
*
* @template T
* @param {any} key
* @param {T} context
Expand Down
1 change: 1 addition & 0 deletions packages/svelte/src/internal/server/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export function set_ssr_context(v) {
/**
* @template T
* @returns {[() => T, (context: T) => T]}
* @since 5.40.0
*/
export function createContext() {
const key = {};
Expand Down
10 changes: 9 additions & 1 deletion packages/svelte/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,12 +450,18 @@ declare module 'svelte' {
type NotFunction<T> = T extends Function ? never : T;
/**
* Returns a `[get, set]` pair of functions for working with context in a type-safe way.
* */
*
* `get` will throw an error if no parent component called `set`.
*
* @since 5.40.0
*/
export function createContext<T>(): [() => T, (context: T) => T];
/**
* Retrieves the context that belongs to the closest parent component with the specified `key`.
* Must be called during component initialisation.
*
* [`createContext`](https://svelte.dev/docs/svelte/svelte#createContext) is a type-safe alternative.
*
* */
export function getContext<T>(key: any): T;
/**
Expand All @@ -465,6 +471,8 @@ declare module 'svelte' {
*
* Like lifecycle functions, this must be called during component initialisation.
*
* [`createContext`](https://svelte.dev/docs/svelte/svelte#createContext) is a type-safe alternative.
*
* */
export function setContext<T>(key: any, context: T): T;
/**
Expand Down
Loading