TS2339:类型“ FC <ButtonProps>”上不存在属性“ whyDidYouRender”

时间:2019-11-14 21:55:48

标签: reactjs typescript

也许是一个愚蠢的问题,但是为什么会出现此错误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;

此行错误:Button.whyDidYouRender = true;

以及我该如何解决?

4 个答案:

答案 0 :(得分:2)

您正在尝试将Button函数视为具有类型Button: ButtonProps,但是Button被声明为Button: React.FC<ButtonProps>

FC<ButtonProps的缩写

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

这意味着它是一个函数,它接受类型为ButtonProps的props对象并返回一个React节点(大致上是html元素的表示形式,如按钮)。

因此,在函数主体内,您可以访问props.labelprops.onClick。您还可以在函数体内访问props.whyDidYouRender

您犯的错误是这些属性存在于参数props上,而不存在于Button函数上。

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;

如果要访问函数内部的whyDidYouRender,则应将其作为道具传递。

如果您确实希望分配Button.whyDidYouRender = true成功,则可以更改Button的类型。

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

这可能不是您真正想要做的,但是从示例中并不清楚您要完成什么,所以这是我能做到的最好的事情。

答案 1 :(得分:2)

像这样添加对react-app-env.d.ts的引用即可解决问题:

/// <reference types="react-scripts" />
/// <reference types="@welldone-software/why-did-you-render" />

答案 2 :(得分:1)

我也遇到了这个问题。您可以在键入类型时使用功能组件的定义来表示为什么要渲染(https://github.com/welldone-software/why-did-you-render/commit/1dadd54860bd5a718520142285700a0f9b4fe901),而不是React自己的FC定义。

然后,您必须import React from '@welldone-software/why-did-you-render'并使用React.FC。考虑给它起别名(import React as WhyDidYouRenderReact from '@welldone-software/why-did-you-render'并使用WhyDidYouRenderReact.FunctionComponent),以便在遇到无法导入的麻烦时,仍可以从“反应”中导入React。

或者,您可以自己定义它,并扩展Tristan提出的FunctionComponenet的现有定义(FC只是FunctionComponent的别名)。这将更正确,因为您将保留FunctionComponent的原始类型。

这里是一个示例,说明了如何避免使用& { whyDidYouRender?: boolean }装饰需要此属性的所有组件,如果您遵循Tristans解决方案,则需要在单独的模块中执行此操作:

declare module 'augmented-react' {
  import { FunctionComponent } from 'react';
  export type FC<P = {}> = FunctionComponent<P> & {
    whyDidYouRender?: boolean
  };
}

然后,您必须从增强反应而不是React导入FC。

答案 3 :(得分:0)

这是打字稿错误... whyDidYouRender未在FC类型上定义。