前言
后台管理系统中,每个模块的列表页,功能模块划分得都比较统一。头部是许多的查询输入框,下面是根据搜索值,展示的 Table
表格。
示例图如下所示:

为减少重复代码的开发,决定将整个页面的功能重新基于 antd
进行一次封装。输入框,查询按钮,表格都通过 props
传入。
使用示例如下:
<PageList
searchProps={searchProps}
search={search}
tableProps={{
columns,
dataSource,
pagination: {
total,
},
rowKey: 'id'
}}
/>
基础组件 PageList
代码 demo
如下:
import React, { useEffect, useState } from 'react';
import { Table } from 'antd';
import { TableProps } from 'antd/es/table';
import { ISearchbarProps } from './index.d';
***
interface IPorps {
searchProps?: SearchbarProps;
tableProps: TableProps<Record<string, any>>;
search: (params: any) => void;
}
export default (props: IProps) {
const { tableProps } = props;
// do something
return (
<main>
<SearchGroup />
<SearchBtns />
<Table { ...tableProps } />
</main>
)
}
问题
其中,searchProps
和 search
都比较简单,直接完整地定义它的类型就行。但 tableProps
是直接使用 ...tableProps
解构给 antd
的 Table
使用,并且当中的数据结构存在着层级嵌套的关系。由于不能确定类型,所以初始时,tableProps
的值类型设置为 tableProps: TableProps<Record<string, any>>
,Record<string, any>
感觉是万能的,什么类型都能兼容。
然后~~~
Table
的 columns
配置里面,如果渲染的值无法直接满足我们的业务需要,需要使用 render: (value: IValueType, record: IRecordType): ReactNode => {<>**</>}
进行渲染。其中,value
的值很容易知道类型。根据 dataIndex
就可以。record
也就是一整行的值。也能知道它的每一项的类型。问题来了,在 render
的 record
处定义了详细的 IRecordType
,而 tableProps
使用的是 Record<string, any>
。

再去查看一个直接使用 antd
的 Table
组件,设置 columns
后,鼠标移动上去时的提示

两边的提示不一样,我们自己封装的会报错。那我们应该怎样写 tableProps
的类型呢?
解决方案
这里就不绕圈子了,主要方法就是,使用 TypeScript
泛型,再结合着类型推论,动态设置 tableProps
类型。
PageList
组件代码 demo
如下:
import React, { useEffect, useState } from 'react';
import { Table } from 'antd';
import { TableProps } from 'antd/es/table';
import { ISearchbarProps } from './index.d';
***
interface IPorps<T> {
searchProps?: SearchbarProps;
tableProps: Pick<TableProps<T>, keyof TableProps<T>>;
search: (params: any) => void;
}
export default function PageList<T extends object=any>(props: IProps<T>) {
const { tableProps } = props;
// do something
return (
<main>
<SearchGroup />
<SearchBtns />
<Table { ...tableProps } />
</main>
)
}
这里有四个比较基础同时又比较关键的点:
-
PageList
需要传入泛型值T
-
泛型值是提供给 TableProps
使用的。这个在node_modules/antd/es/table/table.d.ts
中可以查找到 -
需要使用 Pick
对TableProps<T>
中的类型值进行一次筛选,结合着keyof TableProps<T>
使用。效果类似于ES6
的解构赋值(个人理解)。 -
TypeScript
类型推论
第一步和第二步都很好理解,为什么要有第三步呢?直接使用 tableProps: TableProps<T>;
不行吗?
以下是我自己用两种不同的 tableProps
类型定义方式在鼠标移动上去后的提示状态对比。


很明显,使用第二种方式和 antd
自带的 Table
columns
类型验证更加相似。所以,这里推荐使用第二种方式。
总结
-
写符合 TypeScript
规范的代码 -
尽量少用 any
。不懂的地方,多查一下资料,代码的质量提升了,自己的能力也提高了
当我们感觉困难,有问题时,才正是我们在向上提升的时候。别害怕困难。遇见问题,解决问题。深夜鸡汤走一波,别打我,哈哈哈哈。
另外,自己在使用 TS
的道路上也是正在摸索前进中。文章内容里,难免有不当之处,还望大家批评指正!!!
原文始发于微信公众号(前端学习总结):typescript如何对antd的table进行二次封装
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/83173.html