【发布时间】:2020-03-23 09:23:06
【问题描述】:
我在尝试在 Typescript 中键入抽象组件时遇到问题(来自大量流程经验。) - 以下示例使用的是 Typescript 3.8.3
代码是:
const useSlot = (): [React.ReactNode, React.ComponentType] => {
const slotRef = useRef();
const Slot = ({ children }: { children: React.ReactNode }): React.ReactNode =>
slotRef.current ? createPortal(children, slotRef.current) : null;
return [<div ref={slotRef} />, Slot];
};
export default useSlot;
而用法是:
const [slotLocation, Slot] = useSlot();
return (
<div>
{slotLocation}
<Slot>Some content</Slot>
</div>
);
我遇到的问题是我在网上找不到任何通用的 React 组件类型...在流程中,我们将使用 React.AbstractComponent<Props> 类型来涵盖任何类型的 React 组件。但我在 Typescript 中找不到替代方案,我见过 React.Component、React.FC 和 React.ComponentType;但他们都没有工作。显然它不允许从这些组件类型返回ReactNode(特别是string)。
error TS2345: Argument of type 'ReactNode' is not assignable to parameter of type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<any, any, any>)>'.
Type 'string' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<any, any, any>)>'.
20 render(slotLocation)
~~~~~~~~~~~~
error TS2322: Type '({ children }: { children: React.ReactNode; }) => React.ReactNode' is not assignable to type 'ComponentType<{}>'.
Type '({ children }: { children: React.ReactNode; }) => React.ReactNode' is not assignable to type 'FunctionComponent<{}>'.
Type 'ReactNode' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<any, any, any>)>'.
Type 'string' is not assignable to type 'ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<any, any, any>)>'.
12 return [<div ref={slotRef} />, Slot];
我们如何键入一个可以返回任何类型的 React 节点的通用组件类型?
【问题讨论】:
-
最通用的类型是
JSX.Element -
@RobCo
JSX.Element与ReactNode相同;它是一个渲染节点。在这种情况下,我想返回一个我们需要调用才能渲染的 React 组件;例如<Slot />与<div>{slot}</div>。使用JSX.Element,我们得到这个错误JSX element type 'Slot' does not have any construct or call signatures.(因为它不是可调用的。)
标签: reactjs typescript