1

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'

4
  • 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. Commented Nov 26, 2019 at 15:20
  • @JaredSmith thx, you should answer, not comment, so i can accept your answer :) Commented Nov 26, 2019 at 15:22
  • @JaredSmith thx, i really was struggling to read this errors. Didn't know about whitespace formatting. Commented Nov 26, 2019 at 15:23
  • 1
    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. Commented Nov 26, 2019 at 15:25

1 Answer 1

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:

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'
Sign up to request clarification or add additional context in comments.

2 Comments

Hm, i you sure there is whitespace formatting for vscode console?
No, I just did it by hand in a scratch buffer. After you do the first few your eyes will likely start picking out the relevant bits automatically. One other thing that might help is looking at the actual React d.ts file, it's huge and you have to search around but it's not bad to have at least a rough idea of what the different React types are.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.