如何编写React Functional Component + TypeScript的函数重载?

时间:2019-05-20 02:57:40

标签: javascript reactjs typescript function

我知道如何编写React Functional Component和TypeScript +函数重载。

但是当这两个结合在一起时,我很困惑!

这是一个最小的代码示例,以说明我想要做什么:

import React, { FunctionComponent } from 'react';

type PropType1 = { type: 'type1'; name: string };
type PropType2 = { type: 'type2'; age: number };

// How do I properly hook FunctionComponent + PropType1 + PropType2?
// It's called FunctionComponent right?

function Example({ type, name, age }) {
  if (name === undefined) {
    return (
      <div>
        {type}, {age}
      </div>
    );
  } else {
    return (
      <div>
        {type}, {name}
      </div>
    );
  }
}


export default Example

此示例的用法应如下所示:

<Example type="type1" name="Joseph"/>
// => <div> type1, Joseph </div>

<Example type="type2" age={18}/>
// => <div> type2, 18 </div>

<Example type="type3" name="Joseph" age={18}/>
// => Compile Error!

如何正确钩住FunctionComponent + PropType1 + PropType2?

然后,它叫做FunctionComponent对吗?

3 个答案:

答案 0 :(得分:2)

您可以尝试Union Types并检查组件中的道具类型。

import React, { FunctionComponent } from 'react';

type PropType1 = { type: 'type1'; name: string };
type PropType2 = { type: 'type2'; age: number };

function Example(props: PropType1 | PropType2) {
  if (props.type === 'type1') {
    return (
      <div>
        {props.type}, {props.name}
      </div>
    );
  } else {
    return (
      <div>
        {props.type}, {props.age}
      </div>
    );
  }
}

export default Example;

用法

<Example type="type1" name="Joseph"/>
// => <div> type1, Joseph </div>

<Example type="type2" age={18}/>
// => <div> type2, 18 </div>

<Example type="type3" name="Joseph" age={18}/>
// => Compile Error: Type '"type3"' is not assignable to type '"type1" | "type2"'

<Example type="type1" age={18}/>
// => Compile Error

Demo

答案 1 :(得分:1)

尝试将FC(功能组件)与Union Type一起使用。

FC类型提供了一些额外的属性,例如displayNamedefaultProps等,以使您的功能组件更加安全。

Union类型可以提供函数重载的类似功能。它限制了属性的组合,可以选择PropType1PropType2

const Example: FC<PropType1 | PropType2> = (props) => {
  if (props.type === 'type1') {
    return (
      <div>
        {props.type}, {props.name}
      </div>
    );
  } else {
    return (
      <div>
        {props.type}, {props.age}
      </div>
    );
  }
}

答案 2 :(得分:0)

我自己解决了

import React, {
    PropsWithChildren,
    ReactElement
} from 'react';

type PropType1 = { type: 'type1'; name: string };
type PropType2 = { type: 'type2'; age: number };

function Example(props: PropsWithChildren<PropType1>): ReactElement | null;
function Example(props: PropsWithChildren<PropType2>): ReactElement | null;

function Example(props: {
  type: 'type1' | 'type2';
  name?: string;
  age?: number
}) {

  const {type, name, age} = props

  if (name === undefined) {
    return (
      <div>
        {type}, {age}
      </div>
    );
  } else {
    return (
      <div>
        {type}, {name}
      </div>
    );
  }
}


export default Example