typescript如何对antd的table进行二次封装

前言

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

示例图如下所示:

typescript如何对antd的table进行二次封装
pagedemo

为减少重复代码的开发,决定将整个页面的功能重新基于 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>
)
}

问题

其中,searchPropssearch 都比较简单,直接完整地定义它的类型就行。但 tableProps 是直接使用 ...tableProps 解构给 antdTable 使用,并且当中的数据结构存在着层级嵌套的关系。由于不能确定类型,所以初始时,tableProps 的值类型设置为 tableProps: TableProps<Record<string, any>>Record<string, any> 感觉是万能的,什么类型都能兼容。

然后~~~

Tablecolumns 配置里面,如果渲染的值无法直接满足我们的业务需要,需要使用 render: (value: IValueType, record: IRecordType): ReactNode => {<>**</>} 进行渲染。其中,value 的值很容易知道类型。根据 dataIndex 就可以。record 也就是一整行的值。也能知道它的每一项的类型。问题来了,在 renderrecord 处定义了详细的 IRecordType,而 tableProps 使用的是 Record<string, any>

typescript如何对antd的table进行二次封装
错误的类型提示

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

typescript如何对antd的table进行二次封装
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>
)
}

这里有四个比较基础同时又比较关键的点:

  1. PageList 需要传入泛型值 T
  2. 泛型值是提供给 TableProps 使用的。这个在 node_modules/antd/es/table/table.d.ts 中可以查找到
  3. 需要使用 PickTableProps<T> 中的类型值进行一次筛选,结合着 keyof TableProps<T> 使用。效果类似于 ES6 的解构赋值(个人理解)。
  4. TypeScript 类型推论

第一步和第二步都很好理解,为什么要有第三步呢?直接使用 tableProps: TableProps<T>; 不行吗?

以下是我自己用两种不同的 tableProps 类型定义方式在鼠标移动上去后的提示状态对比。

typescript如何对antd的table进行二次封装
tableProps: TableProps
typescript如何对antd的table进行二次封装
tableProps: Pick<TableProps, keyof TableProps>

很明显,使用第二种方式和 antd 自带的 Table columns 类型验证更加相似。所以,这里推荐使用第二种方式。

总结

  • 写符合 TypeScript 规范的代码
  • 尽量少用 any。不懂的地方,多查一下资料,代码的质量提升了,自己的能力也提高了

当我们感觉困难,有问题时,才正是我们在向上提升的时候。别害怕困难。遇见问题,解决问题。深夜鸡汤走一波,别打我,哈哈哈哈。

另外,自己在使用 TS 的道路上也是正在摸索前进中。文章内容里,难免有不当之处,还望大家批评指正!!!



原文始发于微信公众号(前端学习总结):typescript如何对antd的table进行二次封装

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/83173.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!