Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSX dot notation with forwardRef typescript

I am trying to figure out the types for Dot Notation components with forwardRef.

So I found this example which perfectly illustrates how I currently use dot notation, but doesn't include forwardRef: https://codesandbox.io/s/stpkm

This is what I'm trying to achieve, but can't figure out the typings.

import { forwardRef, useImperativeHandle } from "react";
//
import { ForwardRefRenderFunction } from "react";

const TabToggle: React.FC = () => null;
const TabContent: React.FC = () => null;

interface TabsStatic {
  Toggle: typeof TabToggle;
  Content: typeof TabContent;
}

export interface TabsProps {
  initialIndex?: number;
}

export interface TabsRefMethods {
  show: () => null;
  hide: () => null;
}

export const Tabs: React.ForwardRefRenderFunction<
  TabsRefMethods,
  TabsProps & TabsStatic
> = forwardRef((props, ref) => {
  const openFn = () => null;
  const closeFn = () => null;
  useImperativeHandle(ref, () => ({ show: openFn, hide: closeFn }));
  return null;
});

Tabs.Toggle = TabToggle;
Tabs.Content = TabContent;

Code Sandbox Demo: https://codesandbox.io/s/jsx-dot-notation-in-typescript-with-react-forked-38e1z?file=/src/Tabs.tsx

like image 755
tomk98 Avatar asked Aug 06 '26 22:08

tomk98


1 Answers

There is much easier way to achieve the same result:

const Flex = React.forwardRef(function Flex(...) {
  ...
})

const FlexRow = React.forwardRef(...)
const FlexColumn = React.forwardRef(...)

const FlexNamespace = Object.assign(Flex, {Row: FlexRow, Column: FlexColumn})

export {FlexNamespace as Flex}

Now you can use Flex, Flex.Row, and Flex.Column with TS being happy. The magic line is Object.assign which does not cause the same type issue as Flex.Row = FlexRow does. Don't ask me why, I just accidentally found this 😄

like image 83
Ivan Kleshnin Avatar answered Aug 09 '26 14:08

Ivan Kleshnin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!