我在尝试在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节点的通用组件类型?
答案 0 :(得分:1)
首先,您需要输入ref
并将其传递给createPortal
第二种Slot
的返回类型是ReactPortal
而不是ComponentType
您还应该让TypeScript进行尽可能多的推断,仅键入TypeScript无法推断的内容
我要返回数组as const
来键入元素的位置,而不是显式地键入useSlot
的返回类型
const useSlot = () => {
const slotRef = useRef<HTMLDivElement>(null)
const Slot = ({ children }: { children: React.ReactNode }) =>
slotRef.current ? createPortal(children, slotRef.current) : null
return [<div ref={slotRef} />, Slot] as const
}