Home > Back-end >  How to add static props type for ForwardRefExoticComponent
How to add static props type for ForwardRefExoticComponent

Time:09-30

I have a Modal FC, I need to add two static methods show and hide to it. I have no idea how to add the ModalStaticProps type for the component. So that I can assign show and hide to Modal directly without using type assertion.

import React, { ReactNode, RefAttributes } from 'react';

interface ModalProps {
    title: ReactNode;
}
interface ModalStaticProps {
    show(): void;
    hide(): void;
}
const Modal: React.ForwardRefExoticComponent<ModalProps & RefAttributes<HTMLDivElement>> = React.forwardRef<
    HTMLDivElement,
    ModalProps
>(({ title }: ModalProps, ref) => {
    return <div ref={ref}>{title}</div>;
});

// I want to this after add `ModalStaticProps` type
// Modal.show = () => { };
// Modal.hide = () => { };

// Not this
const ModalComponent = Modal as React.ForwardRefExoticComponent<ModalProps & RefAttributes < HTMLDivElement >> & ModalStaticProps
ModalComponent.show = () => { };
ModalComponent.hide = () => { };

function Consumer() {
    return <div onClick={() => ModalComponent.show()} />
}

TypeScript Playground

CodePudding user response:

It is doable. See Properties declarations on functions. It is possible to do, in a natural way, but it might break your ref types.

Hence, I decided just use Object.assign

See example:

import React, { ReactNode, RefAttributes, ForwardRefExoticComponent } from 'react';

interface ModalProps {
    title: ReactNode;
}

interface ModalStaticProps {
    show(): void;
    hide(): void;
}

const STATIC_PROPS: ModalStaticProps = {
    show: () => { },
    hide: () => { }
}

const withStaticProps = <T,>(
    forwarded: ForwardRefExoticComponent<ModalProps & RefAttributes<HTMLDivElement>>,
    staticProps: T
) => Object.assign(forwarded, staticProps)


const Modal = React.forwardRef<
    HTMLDivElement,
    ModalProps
>(({ title }: ModalProps, ref) => <div ref={ref}>{title}</div>)

const ModalComponent = withStaticProps(Modal, STATIC_PROPS)

function Consumer() {
    return <div onClick={() => ModalComponent.show()} />
}

Playground

See my question regarding this problem

  • Related