javascript - Typescript React `isValidElement` typ-vakt fungerar inte som förväntat
Jag har en tooltip-komponent implementerad så här (jag har förenklat den), som kan användas på två olika sätt genom att skicka ett värde till tooltip-prop, antingen blir det ett JSX-element eller en callback-funktion som slutligen returnerar ett ReactElement:
import { isValidElement, ReactNode, useCallback, useState } from 'react';
import { Portal } from 'react-portal';
interface ChildrenProps {
onHide: () => void;
onShow: () => void;
}
type TooltipCallback = (onHide: () => void) => ReactNode;
export interface Props {
tooltip: ReactNode | TooltipCallback;
children: (props: ChildrenProps) => ReactNode;
}
export function Tooltip({ children, tooltip }: Props) {
const [show, setShow] = useState(false);
const onHide = useCallback(() => {
setShow(false);
}, []);
const onShow = useCallback(() => {
setShow(true);
}, []);
return (
<>
{children({ onHide, onShow })}
<Portal>
{show && tooltip !== null && tooltip !== undefined && (
<div className="tooltip">
{/* TS complains here */}
{isValidElement(tooltip) ? tooltip : tooltip(onHide)}
</div>
)}
</Portal>
</>
);
}
Användning genom att skicka en callback-funktion till tooltip:
<Tooltip
tooltip={(onHide) => (
<div>
<span>
In this tooltip, the only way to close it is by clicking the close button in the tooltip
</span>
<button onClick={onHide}>close</button>
</div>
)}
>
{({ onShow }) => <span onMouseOver={onShow}>Some text that triggers tooltip</span>}
</Tooltip>
Användning genom att skicka ett ReactElement till tooltip:
<Tooltip
tooltip={
<span>This is a tooltip that will be closed when goes away when your mouse leaves</span>
}
>
{({ onShow, onHide }) => (
<span onMouseLeave={onHide} onMouseOver={onShow}>
Some text that triggers tooltip
</span>
)}
</Tooltip>;
Men TypeScript klagar på det:
This expression is not callable.
Not all constituents of type 'string | number | boolean | {} | ReactNodeArray | TooltipCallback' are callable.
Type 'string' has no call signatures.ts(2349)
Men jag antog att eftersom jag har kontrollen isValidElement(tooltip), så är det garanterat att typen av tooltip inte är string | number | {} | ReactNodeArray när man försöker rendera tooltipen med callback-funktionen i else-satsen.
Hur fixar jag detta TS-fel?