Skip to content

Instantly share code, notes, and snippets.

@lucaswinningham
Created September 15, 2023 18:30
Show Gist options
  • Save lucaswinningham/de31566d5caef98a3f985e11e6c6b843 to your computer and use it in GitHub Desktop.
Save lucaswinningham/de31566d5caef98a3f985e11e6c6b843 to your computer and use it in GitHub Desktop.
TypeScript React component events
type Indexable = string | symbol | number;
type PickByKeyName<Type, Name extends Indexable> = {
[Key in keyof Type as Key extends Name ? Key : never]: Type[Key];
};
type PickByKeyType<Type, KeyType> = Pick<Type, {
[Key in keyof Type]: Type[Key] extends KeyType ? Key : never
}[keyof Type]>;
type PickByKey<Type, Name extends Indexable, KeyType> = PickByKeyType<PickByKeyName<Type, Name>, KeyType>;
type NonOptional<Type> = Required<{
[Key in keyof Type]: NonNullable<Type[Key]>;
}>;
type ComponentEventName = `on${Capitalize<string>}`;
type ComponentPropsConstraint = unknown extends ComponentProps<infer R> ? R : never;
// eslint-disable-next-line @typescript-eslint/ban-types
type ComponentEventProps<Type extends ComponentPropsConstraint> = PickByKey<NonOptional<ComponentProps<Type>>, ComponentEventName, Function>;
const MyComponent = ({
hi = 'hey',
onFunc = () => {},
onFuncToo = () => {},
onNonFunc = 42,
someOtherfunc = () => {},
}: {
hi?: string | null,
onFunc?: (() => void) | null,
onFuncToo?: (() => void) | null,
onNonFunc?: number | null,
someOtherfunc?: (() => void) | null,
}) => {
onFunc?.();
onFuncToo?.();
someOtherfunc?.();
return <div>{hi} - {onNonFunc}</div>;
};
type MyComponentEventProps = ComponentEventProps<typeof MyComponent>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment