如何在React + TypeScript 声明带有children的Props

10,398 阅读1分钟

声明带有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

参考链接

www.newline.co/@bespoyasov…