1
votes

How to describe wrapper around any children that tippy accepts that typescript will use correctly?

import Tippy, { TippyProps } from '@tippy.js/react'
import React from 'react'
import 'tippy.js/dist/tippy.css'

Tippy.defaultProps = {
  maxWidth: '500px',
}

export const Tooltip: Tooltip = ({ children, content, ...rest }) => {
  if (!children) return null
  if (!content) return children

  return (
    <Tippy content={content} {...rest}>
      {children}
    </Tippy>
  )
}

interface Tooltip {
  (props: MyProps): React.ForwardRefExoticComponent<TippyProps> | null | React.ReactNode
}

interface MyProps {
  content?: string | React.ReactNode
  children?: React.ReactNode
}

Used like this:

   <Tooltip content='Text'>
        <div>123</div>
   </Tooltip>

Typescript gives me error for children in return statement:

Type 'string | number | true | {} | ReactElement ReactElement Component)> | null) | (new (props: any) => Component)> | ReactNodeArray | ReactPortal' is not assignable to type 'ReactElement ReactElement Component)> | null) | (new (props: any) => Component)>'. Type 'string' is not assignable to type 'ReactElement ReactElement Component)> | null) | (new (props: any) => Component)>'.ts(2322) index.d.ts(6, 3): The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & TippyProps'

1
The error points you right at the problem: you've declared children to be a ReactNode but ReactNode can be a string and Tippy (apparently) won't accept string children. Use ReactElement instead. When debugging typescript errors like this it is frequently helpful (at least until you get more used to reading them) to add whitespace formatting.Jared Smith
@JaredSmith thx, you should answer, not comment, so i can accept your answer :)ZiiMakc
@JaredSmith thx, i really was struggling to read this errors. Didn't know about whitespace formatting.ZiiMakc
Yeah, they're pretty dense. I gave an example in the answer I just posted, all I did was add a few strategically placed carriage returns.Jared Smith

1 Answers

1
votes

The error points you right at the problem: you've declared children to be a ReactNode but ReactNode can be a string and Tippy (apparently) won't accept string children. Use ReactElement instead. When debugging typescript errors like this it is frequently helpful (at least until you get more used to reading them) to add whitespace formatting:

Type 
'string | number | true | {} | ReactElement ReactElement Component)> | null) 
| (new (props: any) => Component)> 
| ReactNodeArray 
| ReactPortal' 
is not assignable to type 
'ReactElement ReactElement Component)> | null) 
| (new (props: any) => Component)>'

Type 'string' is not assignable to type 
'ReactElement ReactElement Component)> | null) 
| (new (props: any) => Component)>'

ts(2322) index.d.ts(6, 3): The expected type comes from property 'children' 
which is declared here on type 'IntrinsicAttributes & TippyProps'