Created
April 11, 2023 04:31
-
-
Save nielk/b177888071a2eb1e89c1a5074253d13c to your computer and use it in GitHub Desktop.
Typesafe getContext setContext (typescript)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts"> | |
import { Context } from './contexts' | |
import { getContext } from './getContext' | |
const loggedUser = getContext(Context.User) | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Readable, Writable } from 'svelte/store' | |
import { isReadableOf, isWritableOf } from './svelte' | |
import { User } from './User' | |
export const UserStore: InjectionKey<Writable<User>> = isWritableOf( | |
(v: any): v is UserStoreType => { | |
return ( | |
v !== null && 'lineNames' in v && 'shortName' in v && 'fullName' in v && 'role' in v | |
) | |
} | |
) | |
export const Context = { | |
User: UserStore, | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { getContext as svelteGetContext, setContext as svelteSetContext } from 'svelte' | |
export type InjectionKey<T = unknown> = (v: any) => v is T | |
type getContext = { | |
<T>(key: InjectionKey<T>): T | |
} | |
export const getContext: getContext = <T>(key: InjectionKey<T>) => { | |
const value = svelteGetContext(key) | |
if (key(value)) { | |
return value | |
} else { | |
throw new Error(`Context ${key} is invalid (missing or wrong type)`) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts"> | |
import { Context } from './contexts' | |
import { setContext } from './setContext' | |
setContext(Context.User, { | |
name: 'foo', | |
shortName: 'bar', | |
fullName: 'Foo Bar', | |
role: 'user', | |
lineNames: ['1', '2', '3'] | |
}) | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { InjectionKey } from './getContext' | |
type setContext = <T>(key: InjectionKey<T>, context: T) => void | |
export const setContext = svelteSetContext as setContext |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { get, Readable, Writable } from 'svelte/store' | |
// Type guards | |
export const isWritable = <T>(value: any): value is Writable<T> => { | |
return value !== null && 'set' in value && 'subscribe' in value && 'update' in value | |
} | |
export const isWritableOf = <T>(typeguard: (v: any) => v is T) => { | |
return (value: any): value is Writable<T> => isWritable(value) && typeguard(get(value)) | |
} | |
export const isReadable = <T>(value: any): value is Readable<T> => { | |
return ( | |
value !== null && 'subscribe' in value && !('set' in value) && !('update' in value) | |
) | |
} | |
export const isReadableOf = <T>(typeguard: (v: any) => v is T) => { | |
return (value: any): value is Readable<T> => isReadable(value) && typeguard(get(value)) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export type User = { | |
name: string, | |
shortName: string, | |
fullName: string, | |
role: string, | |
lineNames: ReadonlyArray<string> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment