带有forwardRef类型脚本的JSX点表示法



我正试图用forwardRef找出Dot Notation组件的类型。

因此,我发现了这个例子,它完美地说明了我目前如何使用点表示法,但不包括forwardRef:https://codesandbox.io/s/stpkm

这就是我正在努力实现的目标,但我搞不懂打字。

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;

代码沙盒演示:https://codesandbox.io/s/jsx-dot-notation-in-typescript-with-react-forked-38e1z?file=/src/Tabs.tsx

有更简单的方法可以实现相同的结果:

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}

现在您可以使用FlexFlex.RowFlex.Column,TS很高兴。魔线是Object.assign不会引起与CCD_ 5相同的类型问题。别问我为什么,我只是不小心发现了这个

我知道并使用过两种可能的方法。两者的权衡略有不同。

第一种方法是在静态组件之间设置(&),并将它们标记为可选组件(Partial),这样在声明组件时就不会出现错误。缺点是它们被表示为可选的,即使它们总是被设置的。

import * as React 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.ForwardRefExoticComponent<
React.PropsWithoutRef<TabsProps> & React.RefAttributes<TabsRefMethods>
> &
Partial<TabsStatic> = React.forwardRef((props, ref) => null);
Tabs.Toggle = TabToggle;
Tabs.Content = TabContent;

另一种选择是使它们成为必需的,但这需要铸造。生成的类型更准确,但它确实需要强制转换。

type TabsComponent = React.ForwardRefExoticComponent<
React.PropsWithoutRef<TabsProps> & React.RefAttributes<TabsRefMethods>
> &
TabsStatic;
export const Tabs = React.forwardRef((props, ref) => null) as TabsComponent;
Tabs.Toggle = TabToggle;
Tabs.Content = TabContent;

甚至更短:

const TabsComponent = () => {
// implement the Tabs component
};
const TabContentComponent = () => {
// implement the TabContent component
};
const TabToggleComponent = () => {
// implement the TabToggle component
};
export const Tabs = Object.assign(forwardRef(TabsComponent),
// a component with forward refs
TabContent: forwardRef(TabContentComponent),
// a component without forwarding
TabToggle
};

最新更新