UNPKG

@modular-component/with-default-props

Version:

ModularComponent stage for handling default props. Part of the @modular-component/default package.

81 lines (72 loc) 2.24 kB
import { addTo, wrap, ModularContext, GetConstraintFor, GetValueGetterFor, StageParams, StageReturn, } from '@modular-component/core/extend' type NonNullableFields<Type> = { [key in keyof Type]-?: undefined extends Type[key] ? never : key }[keyof Type] type NullableFields<Type> = { [key in keyof Type]: undefined extends Type[key] ? key : never }[keyof Type] type OptionalNullable<Type> = { [key in NonNullableFields<Type>]: Type[key] } & { [key in NullableFields<Type>]?: Type[key] } type Merge<Props, DefaultProps extends Partial<Props>> = OptionalNullable<{ [key in keyof Props | keyof DefaultProps]-?: key extends keyof Props ? key extends keyof DefaultProps ? Props[key] extends undefined | infer U ? U : Props[key] : Props[key] : DefaultProps[key] }> extends infer U ? { [key in keyof U]: U[key] } : never type OnlyRequiredInConstraint<Original, Constraint> = { [key in keyof Constraint & keyof Original]: undefined extends Original[key] ? undefined extends Constraint[key] ? never : key : never }[keyof Constraint & keyof Original] type Constraint<Context extends ModularContext> = Partial<Context['props']> & Pick< GetConstraintFor<Context, 'props'>, OnlyRequiredInConstraint< Context['props'], GetConstraintFor<Context, 'props'> > > extends infer U ? { [key in keyof U]: U[key] } : never export function defaultProps< Context extends ModularContext, Default extends Constraint<Context>, >(useDefault: GetValueGetterFor<Context, 'props', Default>) { return addTo<Context>() .on('props') .provide((args): Merge<Context['props'], Default> => { const defaultProps = wrap(useDefault)(args) const merged = { ...(args as { props: Context['props'] }).props, } Object.entries(defaultProps).forEach(([prop, value]) => { if (merged[prop] === undefined) { merged[prop] = value } }) return merged }) } export type WithDefaultProps<Context extends ModularContext> = < Default extends Constraint<Context>, >( ...args: StageParams<typeof defaultProps<Context, Default>> ) => StageReturn<typeof defaultProps<Context, Default>>