问题
最近升级到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。