TypeScript и React - дочерний тип?
У меня есть очень простой функциональный компонент:
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => props.children;
export default aux;
И еще один компонент:
import * as React from "react";
export interface LayoutProps {
children: React.ReactNode
}
const layout = (props: LayoutProps) => (
<Aux>
<div>Toolbar, SideDrawer, Backdrop</div>
<main>
{props.children}
</main>
<Aux/>
);
export default layout;
Я продолжаю получать следующую ошибку:
[TS] Тип элемента JSX 'ReactNode' не является функцией конструктора для элементов JSX. Тип "undefined" не может быть назначен типу "ElementClass". [2605]
Как мне правильно это напечатать?
Ответы
Ответ 1
Чтобы использовать <Aux>
в вашем JSX, это должна быть функция, которая возвращает ReactElement<any> | null
ReactElement<any> | null
Это определение функционального компонента.
Однако в настоящее время он определен как функция, которая возвращает React.ReactNode
, который является гораздо более широким типом. Как написано в React:
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
Убедитесь, что нежелательные типы нейтрализованы, поместив возвращаемое значение во фрагмент React (<></>
):
const aux: React.FC<AuxProps> = props =>
<>{props.children}</>;
Ответ 2
Вот что сработало для меня:
interface Props {
children: JSX.Element[] | JSX.Element
}
Ответ 3
Просто children: React.ReactNode
Ответ 4
Вы можете объявить свой компонент следующим образом:
const MyComponent: React.FunctionComponent = (props) => {
return props.children;
}
Ответ 5
С сайта TypeScript: https://github.com/Microsoft/TypeScript/issues/6471
Рекомендуемая практика - писать тип реквизита как {children?: любой}
Это сработало для меня. Дочерний узел может быть много разных вещей, поэтому явная типизация может пропустить регистры.
Здесь есть более длинное обсуждение вопроса продолжения: https://github.com/Microsoft/TypeScript/issues/13618, но любой подход все еще работает.
Ответ 6
Общий способ найти любой тип - на примере. Прелесть машинописи в том, что у вас есть доступ ко всем типам, если у вас есть правильные файлы @types/
.
Чтобы ответить на этот вопрос сам, я просто подумал о компонентах реакции, использующих опору children
. Первое, что пришло в голову? Как насчет <div />
?
Все, что вам нужно сделать, это открыть vscode и создать новый файл .tsx
в реактивном проекте с @types/react
.
import React from 'react';
export default () => (
<div children={'test'} />
);
Наведите указатель мыши на опору children
, чтобы увидеть тип. А что вы знаете - его тип ReactNode
(нет необходимости в ReactNode[]
).
Затем, если вы нажмете на определение типа, вы сразу перейдете к определению children
, полученному из интерфейса DOMAttributes
.
// node_modules/@types/react/index.d.ts
interface DOMAttributes<T> {
children?: ReactNode;
...
}
Примечание: этот процесс должен использоваться для поиска любого неизвестного типа! Все они просто ждут, когда вы их найдете :)
Ответ 7
Реактивные компоненты должны иметь один узел-обертку или возвращать массив узлов.
Ваш компонент <Aux>...</Aux>
имеет два узла div
и main
.
Попробуйте обернуть своих детей в элемент div
в Aux
.
import * as React from 'react';
export interface AuxProps {
children: React.ReactNode
}
const aux = (props: AuxProps) => (<div>{props.children}</div>);
export default aux;