如何正确定义 antd 可编辑表格列的类型

huangapple go评论90阅读模式
英文:

How to properly define antd editable table columns type

问题

Here's the translation of your code portion:

  1. 我正在使用AntdTypeScript构建一个可编辑的表格,遵循指南 [antd: table edit row](https://ant.design/components/table#components-table-demo-edit-row)。
  2. 目前,它作为一个可编辑表格工作良好,无论是编辑还是显示数据。
  3. 然而,由于我在使用TypeScript,某些列的类型出现了错误。
  4. 这是我的Item定义和列的值
  5. ```typescript
  6. interface CleanFilterItemLabel {
  7. key: string;
  8. name: string;
  9. color?: string;
  10. }
  11. interface CleanFilterItem {
  12. id: React.Key,
  13. state: string,
  14. keyword: string,
  15. create_at: number,
  16. edit_at: number,
  17. author?: string,
  18. level?: number,
  19. group?: number,
  20. labels?: CleanFilterItemLabel[];
  21. }
  22. const edit_tabel_column = [
  23. {
  24. title: t("editPage.level"),
  25. dataIndex: 'level',
  26. editable: true,
  27. },
  28. // 其他列...
  29. ]
  30. const mergedEditColumns = edit_tabel_column.map((col) => {
  31. if (!col.editable) {
  32. return col;
  33. }
  34. return {
  35. ...col,
  36. onCell: (record: CleanFilterItem) => ({
  37. record,
  38. inputType: col.dataIndex,
  39. dataIndex: col.dataIndex,
  40. title: col.title,
  41. editing: isEditing(record),
  42. }),
  43. };
  44. })
  45. <Form form={form} component={false}>
  46. <Table
  47. components={{
  48. body: {
  49. cell: EditableCell
  50. }
  51. }}
  52. rowSelection={rowSelection}
  53. columns={mergedEditColumns} // 这里出现类型错误
  54. className={style.customTable}
  55. dataSource={tableData}
  56. pagination={{ pageSize: 5 }}
  57. scroll={{ y: 360 }}
  58. rowKey={"id"}
  59. />
  60. </Form>

这导致了以下错误:

  1. 类型 '{ 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>[]'
  2. 类型 '{ 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>'
  3. 类型 '{ 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>'
  4. 类型 '{ 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>'
  5. 属性 'onFilter' 的类型不兼容。
  6. 类型 '(value: string, record: any) => boolean' 不能分配给类型 '(value: string | number | boolean, record: CleanFilterItem) => boolean'
  7. 参数 'value' 'value' 的类型不兼容。
  8. 类型 'string | number | boolean' 不能分配给类型 'string'ts(2322)
  9. 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,并尝试将以下定义添加到我的列,但仍然失败:

  1. const edit_tabel_column: (ColumnsType<CleanFilterItem> & {editable?: boolean}[]) = []

我不擅长这种复杂的类型定义,那么我应该如何给它一个正确的定义?

  1. <details>
  2. <summary>英文:</summary>
  3. I&#39;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).
  4. For now it works fine as an editable table, whether editing or displaying data.
  5. However, since i&#39;m using typescript, there&#39;re some errors with column type.
  6. Here&#39;s my Item definition and column value.
  7. ```typescript
  8. interface CleanFilterItemLabel {
  9. key: string;
  10. name: string;
  11. color?: string;
  12. }
  13. interface CleanFilterItem {
  14. id: React.Key,
  15. state: string,
  16. keyword: string,
  17. create_at: number,
  18. edit_at: number,
  19. author?: string,
  20. level?: number,
  21. group?: number,
  22. labels?: CleanFilterItemLabel[];
  23. }
  24. const edit_tabel_column = [
  25. {
  26. title: t(&quot;editPage.level&quot;),
  27. dataIndex: &#39;level&#39;,
  28. editable: true,
  29. },
  30. // {
  31. // title: t(&quot;editPage.labels&quot;),
  32. // dataIndex: &#39;labels&#39;,
  33. // editable: true,
  34. // render: (labels: any) =&gt; (
  35. // &lt;&gt;
  36. // {labels.map((label: any) =&gt; {
  37. // return (
  38. // &lt;Tag key={label.key}&gt;
  39. // {label.name}
  40. // &lt;/Tag&gt;
  41. // )
  42. // })}
  43. // &lt;/&gt;
  44. // ),
  45. // },
  46. {
  47. title: t(&quot;editPage.group&quot;),
  48. dataIndex: &#39;group&#39;,
  49. editable: true,
  50. },
  51. {
  52. title: t(&quot;editPage.state&quot;),
  53. dataIndex: &#39;state&#39;,
  54. editable: true,
  55. filters: [
  56. {
  57. text: t(&quot;editPage.enabled&quot;),
  58. value: &#39;open&#39;,
  59. },
  60. {
  61. text: t(&quot;editPage.disabled&quot;),
  62. value: &#39;closed&#39;
  63. }
  64. ],
  65. filterSearch: false,
  66. onFilter: (value: string, record: any) =&gt; record.state === value,
  67. render: (state: string) =&gt; (
  68. &lt;&gt;
  69. {state === &#39;open&#39; ? &lt;Badge status=&quot;error&quot; text={t(&quot;editPage.disabled&quot;)}/&gt; : &lt;Badge status=&quot;success&quot; text={t(&quot;editPage.enabled&quot;)}/&gt;}
  70. &lt;/&gt;
  71. ),
  72. },
  73. {
  74. title: t(&quot;editPage.keyword&quot;),
  75. dataIndex: &#39;keyword&#39;,
  76. editable: true,
  77. ellipsis: {
  78. showTitle: false,
  79. },
  80. ...getColumnSearchProps(&#39;keyword&#39;),
  81. },
  82. {
  83. title: t(&quot;editPage.createAt&quot;),
  84. dataIndex: &#39;create_at&#39;,
  85. ellipsis: {
  86. showTitle: false,
  87. },
  88. editable: false,
  89. sorter: (a: any, b: any) =&gt; a.create_at - b.create_at,
  90. render: (create_at: number) =&gt; (
  91. &lt;Tooltip title={time.get_date_string_from_timestamp(create_at, &quot;YYYY-MM-DD&quot;)} placement=&#39;top&#39;&gt;
  92. {time.get_date_string_from_timestamp(create_at, &quot;YYYY-MM-DD&quot;)}
  93. &lt;/Tooltip&gt;
  94. ),
  95. },
  96. {
  97. title: t(&quot;editPage.editAt&quot;),
  98. dataIndex: &#39;edit_at&#39;,
  99. ellipsis: {
  100. showTitle: false,
  101. },
  102. editable: false,
  103. sorter: (a: any, b: any) =&gt; a.edit_at - b.edit_at,
  104. render: (edit_at: number) =&gt; (
  105. &lt;Tooltip title={time.get_date_string_from_timestamp(edit_at, &quot;YYYY-MM-DD&quot;)}&gt;
  106. {time.get_date_string_from_timestamp(edit_at, &quot;YYYY-MM-DD&quot;)}
  107. &lt;/Tooltip&gt;
  108. ),
  109. },
  110. {
  111. title: t(&quot;editPage.operation&quot;),
  112. dataIndex: &#39;operation&#39;,
  113. render: (_: any, record: CleanFilterItem) =&gt; {
  114. const editable = isEditing(record);
  115. return editable ? (
  116. &lt;span&gt;
  117. &lt;Typography.Link onClick={() =&gt; saveEditingRow(record.id)} style={{ marginRight: 8 }}&gt;
  118. {t(&#39;editPage.save&#39;)}
  119. &lt;/Typography.Link&gt;
  120. &lt;Popconfirm title={t(&quot;editPage.sureToCancel&quot;)} onConfirm={cancelEditTableRow}&gt;
  121. &lt;a&gt;{t(&#39;editPage.cancel&#39;)}&lt;/a&gt;
  122. &lt;/Popconfirm&gt;
  123. &lt;/span&gt;
  124. ) : (
  125. &lt;div&gt;
  126. &lt;Typography.Link disabled={editingKey !== &#39;&#39;} onClick={() =&gt; editTableRow(record)}&gt;
  127. {t(&#39;editPage.edit&#39;)}
  128. &lt;/Typography.Link&gt;
  129. &lt;Divider type=&quot;vertical&quot; /&gt;
  130. &lt;Typography.Link disabled={editingKey !== &#39;&#39;} onClick={() =&gt; removeRow(record)}&gt;
  131. {t(&#39;editPage.delete&#39;)}
  132. &lt;/Typography.Link&gt;
  133. &lt;/div&gt;
  134. );
  135. },
  136. }
  137. ]
  138. const mergedEditColumns = edit_tabel_column.map((col) =&gt; {
  139. if (!col.editable) {
  140. return col;
  141. }
  142. return {
  143. ...col,
  144. onCell: (record: CleanFilterItem) =&gt; ({
  145. record,
  146. inputType: col.dataIndex,
  147. dataIndex: col.dataIndex,
  148. title: col.title,
  149. editing: isEditing(record),
  150. }),
  151. };
  152. })
  153. &lt;Form form={form} component={false}&gt;
  154. &lt;Table
  155. components={{
  156. body: {
  157. cell: EditableCell
  158. }
  159. }}
  160. rowSelection={rowSelection}
  161. columns={mergedEditColumns} // here comes types error
  162. className={style.customTable}
  163. dataSource={tableData}
  164. pagination={{ pageSize: 5 }}
  165. scroll={{ y: 360 }}
  166. rowKey={&quot;id&quot;}
  167. /&gt;
  168. &lt;/Form&gt;

and it leads to the following errors

  1. Type &#39;({ 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 ... | { ...; })[]&#39; is not assignable to type &#39;(ColumnType&lt;CleanFilterItem&gt; | ColumnGroupType&lt;CleanFilterItem&gt;)[]&#39;.
  2. Type &#39;{ 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 ... | { ...; }&#39; is not assignable to type &#39;ColumnType&lt;CleanFilterItem&gt; | ColumnGroupType&lt;CleanFilterItem&gt;&#39;.
  3. Type &#39;{ title: string; dataIndex: string; editable: boolean; filters: { text: string; value: string; }[]; filterSearch: boolean; onFilter: (value: string, record: any) =&gt; boolean; render: (state: string) =&gt; JSX.Element; ellipsis?: undefined; sorter?: undefined; }&#39; is not assignable to type &#39;ColumnType&lt;CleanFilterItem&gt; | ColumnGroupType&lt;CleanFilterItem&gt;&#39;.
  4. Type &#39;{ title: string; dataIndex: string; editable: boolean; filters: { text: string; value: string; }[]; filterSearch: boolean; onFilter: (value: string, record: any) =&gt; boolean; render: (state: string) =&gt; JSX.Element; ellipsis?: undefined; sorter?: undefined; }&#39; is not assignable to type &#39;ColumnType&lt;CleanFilterItem&gt;&#39;.
  5. Types of property &#39;onFilter&#39; are incompatible.
  6. Type &#39;(value: string, record: any) =&gt; boolean&#39; is not assignable to type &#39;(value: string | number | boolean, record: CleanFilterItem) =&gt; boolean&#39;.
  7. Types of parameters &#39;value&#39; and &#39;value&#39; are incompatible.
  8. Type &#39;string | number | boolean&#39; is not assignable to type &#39;string&#39;.
  9. Type &#39;number&#39; is not assignable to type &#39;string&#39;.ts(2322)
  10. InternalTable.d.ts(14, 5): The expected type comes from property &#39;columns&#39; which is declared here on type &#39;IntrinsicAttributes &amp; TableProps&lt;CleanFilterItem&gt; &amp; { children?: ReactNode; } &amp; { ref?: Ref&lt;HTMLDivElement&gt; | undefined; }&#39;

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

  1. const edit_tabel_column: (ColumnsType&lt;CleanFilterItem&gt; &amp; {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: numbervalue: 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

huangapple
  • 本文由 发表于 2023年4月19日 21:53:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76055369.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定