I have a third party library that export a React Component like this:
// Code I can not change
export default class MyIcon extends React.Component {
...
};
MyIcon.propTypes = {
color?: PropTypes.String
}
I'm working on Typescript so I made the definition for this module:
// Code I can change
declare module '@thirdparty/MyIcon' {
import React from 'react';
interface Props {
color?: string
}
const Icon: React.FC<Props>;
export default Icon;
Now, there is a typescript Component that has this structure:
// Code I can not change
interface IButton {
icon?: React.Component,
text: string
}
export default const Button: FC<IButton> = ({ icon, text }) => {...}
Everything works good till I want to use the MyIcon component and pass it through the Button component. The error I get is Type React.FC<Props> is incompatible with Component<{}, {}, {}>
I endup doing this:
<Button icon={myIcon as unknown as Component} />
But what it kills me is not knowing why is failing.
ANSWER
After talking with the creator of the third party libraries I found they are having the type as Component because they need to change it internally. But doing this, they force my other third party library to behave as a class and not a ReactNode. So basically typing the Icon will work for one of the Third party libraries but it won't allow me to use the other third party library in my project, See code below:
// Ok Code
<Button icon={MyIcon}>Works</Button>
// Wrong Code
<div><MyIcon /> Error on Typescript</div>
Clearly the problem was not the type, but the problem is the way one of the third party libs is requiring the Icon to be a Component instead of a ReactNode. This in my case made a whole problem for me. Hope this helps someone.
Well, you are using React.FC for Icon, but Icon is a class component not a Functional component
try
const Icon: React.Component<Props>
Instead of requiring a class-based component, you could just type icon to allow any node:
interface IButton {
icon?: React.Node,
text: string
}
Here you've said that Icon is of type React.FC<Props>
const Icon: React.FC<Props>;
But here you've said that you expect icon to be either undefined or React.Component.
icon?: React.Component,
React.FC != React.Component.
Change your code to:
icon?: React.FC<Props>
You'd likely need to export that interface:
// icon.tsx
export interface IconProps {
// types here
}
So that you can use it in external modules.