Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TS2339: Property 'whyDidYouRender' does not exist on type 'FC<ButtonProps>'

Maybe a stupid question, but why this error TS2339?!

import * as React from 'react';

import StyledButton from './Button.styled';

interface ButtonProps {
    label?: String;
    onClick?: (e: React.SyntheticEvent) => any | Function;
    whyDidYouRender?: any;
}

const Button: React.FC<ButtonProps> = (props: ButtonProps) => {
    return (
        <StyledButton onClick={props.onClick}>
            {props.label}
        </StyledButton>
    )
};
Button.whyDidYouRender = true;

export default Button;

Error on this line: Button.whyDidYouRender = true;

And how I can fix this??

like image 301
none Avatar asked Dec 05 '22 09:12

none


2 Answers

Edit:

Now that I understand your use case, here's a simpler answer. Change the line where you do the assignment to

(Button as any).whyDidYouRender = true

That will let you set the property once and otherwise treat it as a regular functional component.

Original Answer:

You're trying to treat the function Button as if it had the type Button: ButtonProps, but Button is declared as Button: React.FC<ButtonProps>.

FC<ButtonProps is short for

(props: ButtonProps) => React.Node
// (this is slightly simplified)

which means it's a function that takes in a props object of type ButtonProps and returns a React node (roughly, a representation of an html element like a button).

So, inside the body of the function, you can access props.label and props.onClick, which you do. You could also access props.whyDidYouRender inside the function body.

The mistake you're making is that those properties exist on the argument props, not on the Button function.

const Button: React.FC<ButtonProps> = (props: ButtonProps) => {
    return (
        <StyledButton onClick={props.onClick}>
            {props.label}
            // You can do this, because props: ButtonProps
            {props.whyDidYouRender}
        </StyledButton>
    )
};
// FC<ButtonProps> doesn't have a whyDidYouRender property, so this fails.
Button.whyDidYouRender = true;

If you want to access whyDidYouRender inside the function, you should pass it in as a prop.

If you really want the assignment Button.whyDidYouRender = true to succeed, you could change the type of Button.

Button: React.FC<ButtonProps> & {whyDidYouRender: any} = (props) => ...

That's probably not what you actually want to do, but it's not clear from the example what you are trying to accomplish, so that's the best I can do.

like image 191
Tristan MacKinlay Avatar answered Dec 09 '22 15:12

Tristan MacKinlay


Adding a reference to react-app-env.d.ts like this solved the problem:

/// <reference types="react-scripts" />
/// <reference types="@welldone-software/why-did-you-render" />
like image 25
Vasilii Kovalev Avatar answered Dec 09 '22 13:12

Vasilii Kovalev