Исправление «Компонент» не имеет никакой конструкции или сигнатур вызовов. »ошибка для реквизита по умолчанию с Typescript - PullRequest
3 голосов
/ 31 октября 2019

У меня есть компонент функции MyComponent, и я пытаюсь установить опору по умолчанию для component, чтобы, если ее не указать, корневой узел будет отображаться как "span". Но я получаю следующую ошибку:

TS2604: JSX element type 'Component' does not have any construct or call signatures.
interface IMyComponentProps {
  component?: React.ElementType<React.HTMLAttributes<HTMLElement>>;
}

const MyComponent: React.FunctionComponent<IMyComponentProps> = ({
  className,
  component: Component, <-- complaining
  ...other
}) => (
  <Component className={className}
    {...other}
  />
);

MyComponent.defaultProps = {
  component: 'span'
};

MyComponent.displayName = 'MyComponent';

export default MyComponent;

1 Ответ

2 голосов
/ 31 октября 2019

Мой комментарий был неверным. Попробуйте использовать React.ComponentType в качестве типа для входного компонента.

interface IMyComponentProps {
  Component: React.ComponentType;
}

const MyComponent: React.FunctionComponent<IMyComponentProps> = ({Component, ...other}) => {
  return (<Component {...other} />)
};

Это необходимо использовать следующим образом:

const Span = () => <span>Hey</span>

...

<MyComponent Component={Span}/>

Однако это все еще оставляет проблему настройкипроп по умолчанию в виде строки. Вам нужно было бы установить реквизит по умолчанию как компонент React, который возвращает диапазон. Это компонент более высокого порядка, поэтому компонент React должен иметь как входные, так и выходные данные. Если вы хотите просто передать один элемент JSX, вам нужно будет ввести ввод по-другому и не вызывать ваш элемент prop в качестве его собственного компонента:

interface IMyComponentProps {
  Component: JSX.Element;
}

const MyComponent: React.FunctionComponent<IMyComponentProps> = ({Component, ...other}) => {
  return (<div>{Component}</div>)
};

...

<MyComponent Component={<span>Hey</span>}/>

Возможно, лучший вариант:

Используйте createElement для динамического построения элемента из строкового имени, я не могу придумать другого способа сделать это. Это также дает вам возможность передать компонент Class / Function (хотя пример напечатан только для FC).

interface IMyComponentProps {
  Component: React.FunctionComponent | string;
  textContent: string;
}

const MyComponent: React.FunctionComponent<IMyComponentProps> = ({Component, children, textContent, ...other}) => {
  const newComp = React.createElement(Component,  { ...other }, textContent);

  return newComp;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...