英文:
How to properly define antd editable table columns type
问题
Here's the translation of your code portion:
我正在使用Antd和TypeScript构建一个可编辑的表格,遵循指南 [antd: table edit row](https://ant.design/components/table#components-table-demo-edit-row)。
目前,它作为一个可编辑表格工作良好,无论是编辑还是显示数据。
然而,由于我在使用TypeScript,某些列的类型出现了错误。
这是我的Item定义和列的值。
```typescript
interface CleanFilterItemLabel {
key: string;
name: string;
color?: string;
}
interface CleanFilterItem {
id: React.Key,
state: string,
keyword: string,
create_at: number,
edit_at: number,
author?: string,
level?: number,
group?: number,
labels?: CleanFilterItemLabel[];
}
const edit_tabel_column = [
{
title: t("editPage.level"),
dataIndex: 'level',
editable: true,
},
// 其他列...
]
const mergedEditColumns = edit_tabel_column.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record: CleanFilterItem) => ({
record,
inputType: col.dataIndex,
dataIndex: col.dataIndex,
title: col.title,
editing: isEditing(record),
}),
};
})
<Form form={form} component={false}>
<Table
components={{
body: {
cell: EditableCell
}
}}
rowSelection={rowSelection}
columns={mergedEditColumns} // 这里出现类型错误
className={style.customTable}
dataSource={tableData}
pagination={{ pageSize: 5 }}
scroll={{ y: 360 }}
rowKey={"id"}
/>
</Form>
这导致了以下错误:
类型 '{ title: string; dataIndex: string; editable: boolean; filters?: undefined; filterSearch?: undefined; onFilter?: undefined; render?: undefined; ellipsis?: undefined; sorter?: undefined; } | { title: string; ... 7 more ...; sorter?: undefined; } | ... 6 more ... | { ...; }[]' 不能分配给类型 'ColumnType<CleanFilterItem> | ColumnGroupType<CleanFilterItem>[]'。
类型 '{ title: string; dataIndex: string; editable: boolean; filters?: undefined; filterSearch?: undefined; onFilter?: undefined; render?: undefined; ellipsis?: undefined; sorter?: undefined; } | { title: string; ... 7 more ...; sorter?: undefined; } | ... 6 more ... | { ...; }' 不能分配给类型 'ColumnType<CleanFilterItem> | ColumnGroupType<CleanFilterItem>'。
类型 '{ title: string; dataIndex: string; editable: boolean; filters: { text: string; value: string; }[]; filterSearch: boolean; onFilter: (value: string, record: any) => boolean; render: (state: string) => JSX.Element; ellipsis?: undefined; sorter?: undefined; }' 不能分配给类型 'ColumnType<CleanFilterItem> | ColumnGroupType<CleanFilterItem>'。
类型 '{ title: string; dataIndex: string; editable: boolean; filters: { text: string; value: string; }[]; filterSearch: boolean; onFilter: (value: string, record: any) => boolean; render: (state: string) => JSX.Element; ellipsis?: undefined; sorter?: undefined; }' 不能分配给类型 'ColumnType<CleanFilterItem>'。
属性 'onFilter' 的类型不兼容。
类型 '(value: string, record: any) => boolean' 不能分配给类型 '(value: string | number | boolean, record: CleanFilterItem) => boolean'。
参数 'value' 和 'value' 的类型不兼容。
类型 'string | number | boolean' 不能分配给类型 'string'。ts(2322)
InternalTable.d.ts(14, 5): 预期类型位于此处 'columns' 属性声明在类型 'IntrinsicAttributes & TableProps<CleanFilterItem> & { children?: ReactNode; } & { ref?: Ref<HTMLDivElement> | undefined; }'
我已经检查了这个问题 columns type error when using a custom sorter function on Ant Design table,并尝试将以下定义添加到我的列,但仍然失败:
const edit_tabel_column: (ColumnsType<CleanFilterItem> & {editable?: boolean}[]) = []
我不擅长这种复杂的类型定义,那么我应该如何给它一个正确的定义?
<details>
<summary>英文:</summary>
I'm working on build an editable table using antd in typescript, following the guide [antd: table edit row](https://ant.design/components/table#components-table-demo-edit-row).
For now it works fine as an editable table, whether editing or displaying data.
However, since i'm using typescript, there're some errors with column type.
Here's my Item definition and column value.
```typescript
interface CleanFilterItemLabel {
key: string;
name: string;
color?: string;
}
interface CleanFilterItem {
id: React.Key,
state: string,
keyword: string,
create_at: number,
edit_at: number,
author?: string,
level?: number,
group?: number,
labels?: CleanFilterItemLabel[];
}
const edit_tabel_column = [
{
title: t("editPage.level"),
dataIndex: 'level',
editable: true,
},
// {
// title: t("editPage.labels"),
// dataIndex: 'labels',
// editable: true,
// render: (labels: any) => (
// <>
// {labels.map((label: any) => {
// return (
// <Tag key={label.key}>
// {label.name}
// </Tag>
// )
// })}
// </>
// ),
// },
{
title: t("editPage.group"),
dataIndex: 'group',
editable: true,
},
{
title: t("editPage.state"),
dataIndex: 'state',
editable: true,
filters: [
{
text: t("editPage.enabled"),
value: 'open',
},
{
text: t("editPage.disabled"),
value: 'closed'
}
],
filterSearch: false,
onFilter: (value: string, record: any) => record.state === value,
render: (state: string) => (
<>
{state === 'open' ? <Badge status="error" text={t("editPage.disabled")}/> : <Badge status="success" text={t("editPage.enabled")}/>}
</>
),
},
{
title: t("editPage.keyword"),
dataIndex: 'keyword',
editable: true,
ellipsis: {
showTitle: false,
},
...getColumnSearchProps('keyword'),
},
{
title: t("editPage.createAt"),
dataIndex: 'create_at',
ellipsis: {
showTitle: false,
},
editable: false,
sorter: (a: any, b: any) => a.create_at - b.create_at,
render: (create_at: number) => (
<Tooltip title={time.get_date_string_from_timestamp(create_at, "YYYY-MM-DD")} placement='top'>
{time.get_date_string_from_timestamp(create_at, "YYYY-MM-DD")}
</Tooltip>
),
},
{
title: t("editPage.editAt"),
dataIndex: 'edit_at',
ellipsis: {
showTitle: false,
},
editable: false,
sorter: (a: any, b: any) => a.edit_at - b.edit_at,
render: (edit_at: number) => (
<Tooltip title={time.get_date_string_from_timestamp(edit_at, "YYYY-MM-DD")}>
{time.get_date_string_from_timestamp(edit_at, "YYYY-MM-DD")}
</Tooltip>
),
},
{
title: t("editPage.operation"),
dataIndex: 'operation',
render: (_: any, record: CleanFilterItem) => {
const editable = isEditing(record);
return editable ? (
<span>
<Typography.Link onClick={() => saveEditingRow(record.id)} style={{ marginRight: 8 }}>
{t('editPage.save')}
</Typography.Link>
<Popconfirm title={t("editPage.sureToCancel")} onConfirm={cancelEditTableRow}>
<a>{t('editPage.cancel')}</a>
</Popconfirm>
</span>
) : (
<div>
<Typography.Link disabled={editingKey !== ''} onClick={() => editTableRow(record)}>
{t('editPage.edit')}
</Typography.Link>
<Divider type="vertical" />
<Typography.Link disabled={editingKey !== ''} onClick={() => removeRow(record)}>
{t('editPage.delete')}
</Typography.Link>
</div>
);
},
}
]
const mergedEditColumns = edit_tabel_column.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record: CleanFilterItem) => ({
record,
inputType: col.dataIndex,
dataIndex: col.dataIndex,
title: col.title,
editing: isEditing(record),
}),
};
})
<Form form={form} component={false}>
<Table
components={{
body: {
cell: EditableCell
}
}}
rowSelection={rowSelection}
columns={mergedEditColumns} // here comes types error
className={style.customTable}
dataSource={tableData}
pagination={{ pageSize: 5 }}
scroll={{ y: 360 }}
rowKey={"id"}
/>
</Form>
and it leads to the following errors
Type '({ title: string; dataIndex: string; editable: boolean; filters?: undefined; filterSearch?: undefined; onFilter?: undefined; render?: undefined; ellipsis?: undefined; sorter?: undefined; } | { title: string; ... 7 more ...; sorter?: undefined; } | ... 6 more ... | { ...; })[]' is not assignable to type '(ColumnType<CleanFilterItem> | ColumnGroupType<CleanFilterItem>)[]'.
Type '{ title: string; dataIndex: string; editable: boolean; filters?: undefined; filterSearch?: undefined; onFilter?: undefined; render?: undefined; ellipsis?: undefined; sorter?: undefined; } | { title: string; ... 7 more ...; sorter?: undefined; } | ... 6 more ... | { ...; }' is not assignable to type 'ColumnType<CleanFilterItem> | ColumnGroupType<CleanFilterItem>'.
Type '{ title: string; dataIndex: string; editable: boolean; filters: { text: string; value: string; }[]; filterSearch: boolean; onFilter: (value: string, record: any) => boolean; render: (state: string) => JSX.Element; ellipsis?: undefined; sorter?: undefined; }' is not assignable to type 'ColumnType<CleanFilterItem> | ColumnGroupType<CleanFilterItem>'.
Type '{ title: string; dataIndex: string; editable: boolean; filters: { text: string; value: string; }[]; filterSearch: boolean; onFilter: (value: string, record: any) => boolean; render: (state: string) => JSX.Element; ellipsis?: undefined; sorter?: undefined; }' is not assignable to type 'ColumnType<CleanFilterItem>'.
Types of property 'onFilter' are incompatible.
Type '(value: string, record: any) => boolean' is not assignable to type '(value: string | number | boolean, record: CleanFilterItem) => boolean'.
Types of parameters 'value' and 'value' are incompatible.
Type 'string | number | boolean' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.ts(2322)
InternalTable.d.ts(14, 5): The expected type comes from property 'columns' which is declared here on type 'IntrinsicAttributes & TableProps<CleanFilterItem> & { children?: ReactNode; } & { ref?: Ref<HTMLDivElement> | undefined; }'
I've checked this question columns type error when using a custom sorter function on Ant Design table and try add the following definition to my column, but it still fails
const edit_tabel_column: (ColumnsType<CleanFilterItem> & {editable?: boolean}[]) = []
I'm not good at such a complex type definiation, so how should i give it a proper definition?
答案1
得分: 0
问题在于onFilter
列的类型定义为value: string | number | boolean, record: Item
如果我们定义自己的onFilter
类型,定义如下:
value: number, record: Item
它会抛出错误,称value: number
与value: string | number | boolean
不兼容。
解决办法是让它们具有相同的类型定义,即string | number | boolean
。
这是我的复制链接一旦可编辑表格列具有onFilter属性,TypeScript声称mergedColumns与columns的类型不兼容
英文:
The problem is the column onFilter
type has a type definition
value: string | number | boolean, record: Item
If we define our own onFilter
type with definition like
value: number, record: Item
It will throw errors, claim tha value: number
is not compatiable with value: string | number | boolean
.
The solution is to let them have the same type definition as string | number | boolean
.
And here's my reproduction link Once on editable table columns has onFilter property, typescript claims that mergedColumns is not assignable type with columns
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论