@types/react@18之break change React.FC

1,803 阅读1分钟

问题

最近升级到React 18引入的第三方组件报类型'IProps'上不存在属性 'children'Property 'children' does not exist on type 'IProps'。查看相关资料后发现,@types/react@18 引入了 break change,去掉了React.FC默认属性children

@types/react@17

type FC<P = {}> = FunctionComponent<P>;

interface FunctionComponent<P = {}> {
    (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
    propTypes?: WeakValidationMap<P> | undefined;
    contextTypes?: ValidationMap<any> | undefined;
    defaultProps?: Partial<P> | undefined;
    displayName?: string | undefined;
}

@types/react@18

type FC<P = {}> = FunctionComponent<P>;

interface FunctionComponent<P = {}> {
    (props: P, context?: any): ReactElement<any, any> | null;
    propTypes?: WeakValidationMap<P> | undefined;
    contextTypes?: ValidationMap<any> | undefined;
    defaultProps?: Partial<P> | undefined;
    displayName?: string | undefined;
}

解决办法:

1、如果是内部组件,修改组件IProps。

修改前:

import React from "react";

interface IProps {
  style: React.CSSProperties;
}

const Layout: React.FC<IProps> = (props) => {
  return <div className="layout" style={props.style}>{props.children}</div>;
};

export default Layout;

修改后:

import React, { PropsWithChildren } from "react";

interface IProps {
  style: React.CSSProperties;
}

const Layout: React.FC<PropsWithChildren<IProps>> = (props) => {
  return (
    <div className="layout" style={props.style}>
      {props.children}
    </div>
  );
};

export default Layout;

2、如果是外部组件,可以等待组件作者修复或者加上@ts-ignore忽略。

写在最后:

这个问题之前一直困扰着我,知道我看到antd一个的Issue #35115,里面提到一篇博客Why I don't use React.FC)才算解除了我的困惑。以后使用React.FC都需要显式声明children