0

I'm writing a quick wrapper interface. I'm looking for some mystery types:

Let Foo be some React component that accepts props of type FooProps.

Let X be the interface that represents both any generic React component or any HTML element. Where Foo extends X but also div extends X. X is anything that can be turned into a JSX.Element by <X></X>

Let Y<T extends X> be the props of our T, which is again any element such as Foo or div. Where Y<Foo> = FooProps, and Y<div> = { className: string, ... }

We could write:

interface WrapperProps<T extends X>{
    children?: React.ReactNode;
    attributes?: Y<T>;
}

Then we could write:

const props: WrapperProps<T> = ...;
const el: JSX.Element = (
    <T {...attributes}>
        { children }
    </T>
);

What are these mystery types X and Y?

1 Answer 1

1

I believe what you're looking for is:

type WrapperProps<T extends keyof JSX.IntrinsicElements | React.JSXElementConstructor<any>> = {
    children?: React.ReactNode;
    attributes: Omit<React.ComponentProps<T>, 'children'>;
}

playground link

Notice the required attributes property. While you can make any of the properties optional you cannot omit them at all.

React types used here:

JSX.IntrinsicElements (too big to include here).

JSXElementConstructor:

type JSXElementConstructor<P> =
    | ((props: P) => ReactElement<any, any> | null)
    | (new (props: P) => Component<P, any>);

ReactComponentProps:

type ComponentProps<T extends keyof JSX.IntrinsicElements | JSXElementConstructor<any>> =
    T extends JSXElementConstructor<infer P>
        ? P
        : T extends keyof JSX.IntrinsicElements
            ? JSX.IntrinsicElements[T]
            : {};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.