I have a tooltip component implemented like this (I have simplified it), which can be used in two different ways by passing a value to tooltip
prop, either it will be a JSX element or a callback function that returns a ReactElement
eventually:
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>
</>
);
}
Usage by passing a callback function to 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>
Usage by passing a ReactElement
to 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>;
But typescript is complaining about it:
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)
However, I assumed since I have the isValidElement(tooltip)
check, then it is guaranteed that type of the tooltip is not string
| number
| {}
| ReactNodeArray
when trying to render the tooltip with callback function in the else clause.
How do I fix this TS error?
1条答案
按热度按时间qkf9rpyu1#
您的程式码问题在于工具提示属性宣告为类型
ReactNode | TooltipCallback
,因此TypeScript不知道它在条件的else子句中永远是TooltipCallback。若要修正这个问题,您可以在else子句的tooltip变数中加入判断提示,告诉TypeScript它在该点上绝对是TooltipCallback。您可以在tooltip变数之后加入做为TooltipCallback来完成这个动作,如下所示:
通过此更改,TypeScript将不再抱怨else子句中对tooltip()的调用。
以下是应用了更改的完整代码: