Довольно новый для TypeScript, и вам необходимо реализовать действие переключения между компонентом таблицы данных и древовидным представлением с использованием библиотеки IBM Carbon в React.js. Получение следующей ошибки из этой строки -
<TableHeader {...getHeaderProps({ header })} key = {header.key}> {header.header}</TableHeader>
Ошибка:
'Type '{ children: ReactNode; key: string; isSortable: boolean | undefined; isSortHeader: boolean; onClick: (e: MouseEvent) => void; sortDirection: DataTableSortState; }' is not assignable to type 'TableHeaderProps'.
Types of property 'onClick' are incompatible.
Type '(e: MouseEvent) => void' is not assignable to type 'MouseEventHandler<HTMLButtonElement>'.
Types of parameters 'e' and 'event' are incompatible.
Type 'MouseEvent<HTMLButtonElement, MouseEvent>' is missing the following properties from type 'MouseEvent': layerX, layerY, offsetX, offsetY, and 16 more.'
Нужны некоторые подсказки о том, почему мы получаем ошибку и как ее устранить/избежать в дальнейшем. Цените всю помощь, которую я могу получить.
import React from 'react';
import TreeView from '@carbon/react/lib/components/TreeView/TreeView';
import TreeNode from '@carbon/react/lib/components/TreeView/TreeNode';
import { Document } from '@carbon/icons-react';
import { DataTable, Table, TableBody, TableCell, TableContainer, TableHead, TableHeader, TableRow } from '@carbon/react';
import Button from '@carbon/react/lib/components/Button/Button';
const headers = [
{ key: 'name', header: 'Name' },
{ key: 'path', header: 'Path' },
{ key: 'description', header: 'Description' },
];
const rows = [
{ id: 'node-1', name: 'Node 1', path: 'Root', description: 'Activity for Sales scenario' },
{ id: 'node-1-1', name: 'Node 1.1', path: 'Root/Node 1', description: 'Activity for Sales scenario' },
{ id: 'node-2', name: 'Node 2', path: 'Root', description: 'Activity for Sales scenario' },
{ id: 'node-3', name: 'Node 3', path: 'Root', description: 'Activity for Sales scenario' },
{ id: 'node-3-1', name: 'Node 3.1', path: 'Root/Node 3', description: 'Activity for Sales scenario' },
{ id: 'node-3-2', name: 'Node 3.2', path: 'Root/Node 3', description: 'Activity for Sales scenario' },
{ id: 'node-3-3', name: 'Node 3.3', path: 'Root/Node 3', description: 'Activity for Sales scenario' },
{ id: 'node-4', name: 'Node 4', path: 'Root', description: 'Activity for Sales scenario' },
{ id: 'node-4-1', name: 'Node 4.1', path: 'Root/Node 4', description: 'Activity for Sales scenario' },
{ id: 'node-4-2', name: 'Node 4.2', path: 'Root/Node 4', description: 'Activity for Sales scenario' },
{ id: 'node-4-2-1', name: 'Node 4.2.1', path: 'Root/Node 4/Node 4.2', description: 'Activity for Sales scenario' },
{ id: 'node-4-3', name: 'Node 4.3', path: 'Root/Node 4', description: 'Activity for Sales scenario' },
];
interface TreeNodeComponentProps {
selectedNodes: string[];
handleSelect: (event: { id: string }) => void;
toggleNode3Expansion: () => void;
isNode3Expanded: boolean;
}
const TreeNodeComponent: React.FC<TreeNodeComponentProps> = ({
selectedNodes,
handleSelect,
toggleNode3Expansion,
isNode3Expanded,
}) => {
const [showDataTable, setShowDataTable] = React.useState<boolean>(false);
const toggleView = () => {
setShowDataTable(!showDataTable);
};
return (
<div>
<Button kind = "secondary" onClick = {toggleView}>
{showDataTable ? 'Show Tree View' : 'Show Data Table'}
</Button>
{showDataTable ? (
<DataTable rows = {rows.filter(row => selectedNodes.includes(row.id))} headers = {headers}>
{({ rows, headers, getHeaderProps, getRowProps }) => (
<TableContainer>
<Table>
<TableHead>
<TableRow>
{headers.map(header => (
<TableHeader {...getHeaderProps({ header })} key = {header.key} >
{header.header}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map(row => (
<TableRow {...getRowProps({ row })} key = {row.id}>
{row.cells.map(cell => (
<TableCell key = {cell.id}>{cell.value}</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)}
</DataTable>
) : (
<TreeView selected = {selectedNodes} onSelect = {handleSelect}>
<TreeNode id = "node-1" label = {<><Document /> Node 1</>} isExpanded>
<TreeNode id = "node-1-1" label = "Node 1.1" />
</TreeNode>
<TreeNode id = "node-2" label = {<><Document /> Node 2</>} />
<TreeNode id = "node-3" label = {<><Document /> Node 3</>} isExpanded = {isNode3Expanded}>
<TreeNode id = "node-3-1" label = "Node 3.1" />
<TreeNode id = "node-3-2" label = "Node 3.2" />
<TreeNode id = "node-3-3" label = "Node 3.3" disabled />
</TreeNode>
<TreeNode id = "node-4" label = {<><Document /> Node 4</>} isExpanded>
<TreeNode id = "node-4-1" label = "Node 4.1" disabled />
<TreeNode id = "node-4-2" label = "Node 4.2">
<TreeNode id = "node-4-2-1" label = "Node 4.2.1" />
</TreeNode>
<TreeNode id = "node-4-3" label = "Node 4.3" disabled />
</TreeNode>
</TreeView>
)}
</div>
);
};
export default TreeNodeComponent;
Кажется, это известная ошибка в библиотеке Carbon React. По сути, проблема в том, что некоторые компоненты определяют обработчик onClick как MouseEvent
, тогда как другие используют React.MouseEvent
(который является общим), в этом случае getHeaderProps
возвращает объект, определенный как MouseEvent
но TableHeader
ожидает React.MouseEvent<HTMLButtonElement>
.
Поскольку вы напрямую передаете возвращаемое значение getHeaderProps
, которое обрабатывается самой библиотекой, было бы неплохо ввести его как any
, поскольку типирование в любом случае управляется библиотекой:
<TableRow>
{headers.map((header) => (
<TableHeader
{...(getHeaderProps({ header }) as any)}
key = {header.key}
>
{header.header}
</TableHeader>
))}
</TableRow>
Разве так не должно быть
...getHeaderProps(header)
?