TypeScript項目實踐之 Omit 特性

前言javascript

入職兩個月以來天天都在接觸 TypeScript,但其實用的還不是很好,常常踩坑。因此我接下來也會嘗試着更新本身該系列文章,目的是除了鞏固總結本身的所學以外,也但願可以幫助到正在學習TypeScript但沒有在真實項目實踐中使用過TypeScript的人們。java

Omit 介紹react

Omit的中文意思是 忽略 ,是 TypeScript 3.5 版本推出的特性,如下是官網的介紹數組

TypeScript 3.5 添加了新的 Omit 輔助類型,這個類型用來建立從原始類型中移除了某些屬性的新類型。
複製代碼

由於是我想寫的主要是在真實項目中對於該特性的實踐,所以官網裏的例子我就不列舉了。bash

需求介紹antd

由於我所在小組負責的是偏向企業服務的,相似於後臺管理,所以會遇到不少的 Table, 採用的 UI框架是 ant-design, 因此我會列舉一個。框架

如今咱們須要對錶格作一個篩選功能,這會用到ant-desighTablefilterDropdown屬性,以下圖所示:函數

那麼如何使用呢,仍是看下面的代碼吧:學習

{
    title: 'Age',
    dataIndex: 'age',
    key: 'age',
    filterType: true,
    filterDropdown: ({ confirm, selectedKeys, setSelectedKeys }) => (
      <DropDownList confirm={confirm} selectedKeys={selectedKeys} setSelectedKeys={setSelectedKeys} /> ), } 複製代碼

filterDropdown 能夠的值能夠是一個函數,其中注意到其參數的 props 的類型是 FilterDropdownProps, 這是個什麼東西呢,咱們進去源碼看看:ui

export interface FilterDropdownProps {
    prefixCls: string;
    setSelectedKeys: (selectedKeys: React.Key[]) => void;
    selectedKeys: React.Key[];
    confirm: () => void;
    clearFilters?: () => void;
    filters?: ColumnFilterItem[];
    visible: boolean;
}
複製代碼

能夠看到FilterDropdown有不少的屬性, 其中有 selectedKeyssetSelectedKeys, 這也就是爲何咱們在上面使用 filterDropdown 的時候能夠經過解構賦值拿到 selectedKeyssetSelectedKeys

注意點

咱們看到 setSelectedKeys,其參數類型是 React.Key[] 類型的,

經過上圖能夠發現,這個 setSelectedKeys 只能接收一個 string 或者 number 類型的數組。

那若是咱們在需求裏遇到了要用string或者number類型以外的類型怎麼辦?

Omit 用法

上面介紹的時候提到,Omit 的意思是忽略,在這裏,咱們應該理解爲 Omit 能夠忽略某個類型的某些屬性,假設咱們如今想要讓 setSelectedKeysselectedKeys 能接收一個非string 或者 number 類型的數組,那麼咱們只需使用 Omit 忽略 這兩個屬性,而後咱們本身給這兩個屬性賦值新的類型是否是就能夠了?

Omit <T, K>

其中 Ttype也就是類型的簡寫, Kkey 的簡寫,因此這裏的意思就是忽略該類型的key屬性

import { FilterDropdownProps } from 'antd/es/table'

type TagProps = {
    slug: string
    name: string
}

type MyFilterDropdownProps = Omit<FilterDropdownProps, 'selectedKeys' | 'setSelectedKeys'> & {
    selectedKeys: TagProps
    setSelectedKeys: (selectedKeys: TagProps[]) => void
}
複製代碼

上面這段代碼,先看左邊 Omit<FilterDropdownProps, 'selectedKeys' | 'setSelectedKeys'>, 這裏的意思就是要忽略 FilterDropdownPropsselectedKeyssetSelectedKeys 屬性,而後咱們還作了一步最重要的操做,就是經過 & 符號將咱們本身定義的 selectedKeyssetSelectedKeysFilterDropdownProps 剩下的屬性組合起來了,最後再賦值給 MyFilterDropdownProps 類型。

那麼這個時候,咱們就已經將FilterDropdownProps裏的 selectedKeyssetSelectedKeys 改形成了咱們但願可以接收的類型。

還沒結束

我相信用過filterDropdown這個屬性的同窗,必定都知道該屬性是在 column 中使用的,column是一個對象數組,每個對象表明一列,既然filterDropdown是用在column中的,那麼咱們最後要作的就是把column中的filterDropdown屬性替換成咱們本身定義的類型便可。

在此以前,咱們先看看column裏有哪些屬性,上源碼:

能夠看到,這個ColumnType就是column 數組中每一個對象可使用的屬性,其中就有 filterDropdown 屬性,因此咱們最後一步操做以下代碼:

import React, { FC } from 'react'
import { ColumnType, FilterDropdownProps, TableProps } from 'antd/es/table'

type TagProps = {
    slug: string
    name: string
}

type MyFilterDropdownProps = Omit<FilterDropdownProps, 'selectedKeys' | 'setSelectedKeys'> & {
    selectedKeys: TagProps
    setSelectedKeys: (selectedKeys: TagProps[]) => void
}

// 注意這裏原來的 FilterDropdownProps 已經被替換成咱們自定義的 MyFilterDropdownProps
type MyColumnType<T> = Omit<ColumnType<T>, 'filterDropdown'> & {
    filterDropdown?: React.ReactNode | ((props: MyFilterDropdownProps) => React.ReactNode);
}

// 又由於 column 是 Table 的屬性
type MyTableProps<T> = Omit<TableProps<T>, 'column'> & {
    columns?: MyColumnType<T>;
}

type User = {
    //
}

// MyTable 能夠像普通的Table 同樣使用, 由於其類型是咱們改造過的 TableProps
// 所以 Table 能夠接收的屬性 MyTable 也一樣能夠接收
const MyTable: FC<MyTableProps<User>> = (props) => {
    const { xxx, xxx, xxx, ...restProps } = props
    
    const columns: MyColumnType<User>[] = [{
        //,
        //,
        filterDropdown: ({selectedKeys, setSelectedKeys}) => {
            // 此時的 selectedKeys 跟 setSelectedKeys 接收的類型已經被改形成 TagProps 了
            // 而不是 antd table 定義的類型了
        })
    }]
    
    return <Table {...restProps} columns={columns} /> } 複製代碼

其實到這裏,關於 Omit的用法就講完了,我想經過上面這幾段代碼,應該能夠很好的說明Omit在實踐當中是如何使用的。

謝謝觀看小弟的文章,但願對各位有幫助。
複製代碼
相關文章
相關標籤/搜索