声明带有children的Props,有很多种方式。
ReactNode
直接在prop上手动添加children属性
import {ReactNode} from 'react';
type ComponentProps = {
foo: string;
children: ReactNode;
}
假如children是可选的,可以添加一个可选标记?
import {ReactNode} from 'react';
type ComponentProps = {
foo: string;
children?: ReactNode;
}
不过,不建议这种方式,因为每次都需要手动添加children
PropsWithChildren
PropsWithChildren
本身已经封装了children声明,源码如下
// react/index.d.ts
//url:https://github.com/DefinitelyTyped/DefinitelyTyped/blob/d076add9f29db350a19bd94c37b197729cc02f87/types/react/index.d.ts#L822
type PropsWithChildren<P> = P & { children?: ReactNode };
所以,直接通过泛型声明
type ComponentProps = PropsWithChildren<{foo: string}>;
React.FunctionComponent 或 React.FC
当创建一个函数式组件的时候,React.FC 泛型接口已经包含了children的声明。也是通过PropsWidthChildrend实现的。源码如下
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;
}
根据接口声明,我们可以通过泛型把类型参数传入其中
type ComponentProps = {
foo: string
}
const Component: React.FC<ComponentProps> = ({foo,children}) =><span>{foo}{children}</span>
Class Components
当创建的是class组件,你需要继承React.Component 类型
type AvatarProps = {
src: string;
}
class Avatar extends React.Component<AvatarProps> {
render() {
const {src, children} = this.props;
return <>
<img src={src} alt="User photo" />
{children}
</>
}
}
最后
建议使用函数式组件,所以就要用到React.FC 这种方式,全面拥抱 React Hooks