Как написать перегрузку функции React Functional Component + TypeScript? - PullRequest
2 голосов
/ 20 мая 2019

Я знаю, как написать перегрузку функционального компонента React и функции 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 ]

2 голосов
/ 20 мая 2019

Вы можете попробовать Типы объединения и проверить тип реквизита в компоненте.

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

Демо

1 голос
/ 20 мая 2019

Попробуйте использовать FC, функциональный компонент с Тип соединения .

Тип

FC обеспечивает некоторые дополнительные свойства, например, displayName, defaultProps и т. Д., Чтобы сделать ваш функциональный компонент более безопасным.

Тип

Union может обеспечивать аналогичные функции перегрузки функций. Он ограничивает комбинацию свойств, выбор которых PropType1 или PropType2

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>
    );
  }
}
0 голосов
/ 20 мая 2019

Я решил это сам

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...