Skip to content

Instantly share code, notes, and snippets.

@adamgreg
Created October 8, 2023 16:03
Show Gist options
  • Save adamgreg/b4eecbbe764c76f068d661d2222ca893 to your computer and use it in GitHub Desktop.
Save adamgreg/b4eecbbe764c76f068d661d2222ca893 to your computer and use it in GitHub Desktop.
Additional types for preact/compat . Used by Radix UI.
import { ComponentClass, VNode } from "preact";
import "preact/compat";
declare module "preact/compat" {
export type ElementType = JSX.ElementType;
export type ComponentPropsWithoutRef<T extends ElementType> = PropsWithoutRef<
ComponentProps<T>
>;
export type PropsWithRef<P> =
// Just "P extends { ref?: infer R }" looks sufficient, but R will infer as {} if P is {}.
"ref" extends keyof P
? P extends { ref?: infer R }
? string extends R ? PropsWithoutRef<P> & { ref?: Exclude<R, string> }
: P
: P
: P;
export type ComponentPropsWithRef<T extends ElementType> = T extends
ComponentClass<infer P>
? PropsWithoutRef<P> & RefAttributes<InstanceType<T>>
: PropsWithRef<ComponentProps<T>>;
export type ElementRef<
C extends
| ForwardRefExoticComponent<any>
| { new (props: any): Component<any> }
| ((props: any, context?: any) => VNode)
| keyof JSX.IntrinsicElements,
> = NonNullable<ComponentPropsWithRef<C>["ref"]> extends preact.Ref<
infer Instance
> ? Instance
: never;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment