required-react-context
Version:
A simple React Context wrapper that throws an error if it is used without being provided
29 lines (25 loc) • 1.5 kB
TypeScript
import { Context, FC, PropsWithChildren, ConsumerProps } from 'react';
type Compute<T> = {
[K in keyof T]: T[K];
} & unknown;
declare const UNSET_VALUE: unique symbol;
interface Names {
name: string;
contextName?: string;
providerName?: string;
providerProp?: string;
consumerName?: string;
hookName?: `use${string}`;
}
type GetName<N extends Names, K extends keyof Names, Fallback extends string> = N[K] extends string ? N[K] : Fallback;
type GetContextName<N extends Names> = GetName<N, "contextName", `${Capitalize<N["name"]>}Context`>;
type GetProviderName<N extends Names> = GetName<N, "providerName", `${Capitalize<N["name"]>}Provider`>;
type GetProviderProp<N extends Names> = GetName<N, "providerProp", N["name"]>;
type GetConsumerName<N extends Names> = GetName<N, "consumerName", `${Capitalize<N["name"]>}Consumer`>;
type GetHookName<N extends Names> = GetName<N, "hookName", `use${Capitalize<N["name"]>}`>;
interface NamedContext<T> extends Context<T> {
displayName: string;
providerName: string;
}
type NamedContextUtils<T, N extends Names, IsRequired extends boolean = true> = Compute<Record<GetContextName<N>, Context<IsRequired extends true ? T | typeof UNSET_VALUE : T>> & Record<GetProviderName<N>, FC<PropsWithChildren<Record<GetProviderProp<N>, T>>>> & Record<GetConsumerName<N>, FC<ConsumerProps<T>>> & Record<GetHookName<N>, () => T>>;
export { type Names as N, UNSET_VALUE as U, type NamedContextUtils as a, type NamedContext as b };