项目上使用ts一年多了,一边写,一边看,总结了一些小技巧,写了一些分享给大家,如果对你有所帮助就转评赞三连来一个,那么我们开始今天的正题;
(1)、type联合类型简化
我们先看下面一个联合类型案例:
const vegetablesNum = {
tomatoes: 12,
radishs: 10,
cabbages: 1
};
type Vegetables = |
{
tomatoes: number
} | {
radishs: number
} | {
cabbages: number
};
const cookie: Vegetables = {
tomatoes: 10,
}
上面的type + |
方式实现了一个不为空{}
任意key
组合的对象,也许很多人在想是否可以通过interface + ?
可选属性方式实现,答案是不可以的,因为这样处理总会出现{}
或者固定key的情况;
然而上述方案有个致命问题,如果vegetablesNum
里面新增的其他的蔬菜,我们的type Vegetables
就需要跟着改动,这样Vegetables
这个类型定义就显得很笨;所以我们需要优化这个Vegetables
类型,让他适配更多的情况,具体如下:
const vegetablesNum = {
tomatoes: 12,
radishs: 10,
cabbages: 1
};
type NewVegetables = {
[K in keyof typeof vegetablesNum]: {
[K2 in K]: typeof vegetablesNum[K2]
}
}[keyof typeof vegetablesNum]
const cookie2: NewSingleVegetable = {
tomatoes: 123,
cabbages: 123
}
上面实现的NewVegetables
可以随时满足vegetablesNum
数据结构的变化,已经很nice了,可是如果有一天隔壁工位老王,说你这个类型很nice,我要用,开始c + v
? 好像无聊的代码又增加了一份,因此我们考虑一下泛型思维解决重复劳动?看一看具体办法吧:
const vegetablesNum = {
tomatoes: 12,
radishs: 10,
cabbages: 1
};
const animals = {
pig: 20,
monkey: 50,
}
type SingleRecord<T = Record<string, any>> = {
[K in keyof T]: {
[R in K]: T[R]
}
}[keyof T]
const cookie3: SingleRecord<typeof vegetablesNum> = {
tomatoes: 123
}
const monkeys: SingleRecord<typeof animals> = {
monkey: 50
}
这样老王就可以开心使用摸鱼技巧了;
(2)、extends与泛型优化你的函数
在实际情况中,我们写一些通用方法,为了通用性放宽类型限制,虽然方便了,但是问题在与ts对于他的语法检测也会随之放宽,有一些意想不到的错误出现,如下代码所示:
let obj = {
name: 'kanade',
age: 20
}
function getInfo(obj: Record<string, any>, key: string) {
return obj[key]
}
getInfo(obj, 'age1')
getInfo
传入非obj的key值错误,会有意想不到undefined
取值出现,遇到这样的问题,怎么能让我们函数看起来匹配不同类型数据,还有良好的语法纠错提示呢?(不要在乎示例,你可能会说直接obj.name,放过他吧,他还只是一个example~~)
下面有请我们的extends
和泛型同学登场,来改造我们的函数
let obj = {
name: 'kanade',
age: 20
}
function getInfoNew<T, K extends keyof T>(obj: T, key: K) {
return obj[key]
}
getInfoNew(obj, 'age')
效果图,这么良好的提示你们爱了么
(3)、as类型断言 + keyof 让遍历更加友好
我们看一看蔬菜大礼包的例子
const vegetables = {
tomatoes: 12,
radishs: 10,
cabbages: 1
}
Object.keys(vegetables).forEach((key) => {
console.log(`${key}-数量-${vegetables[key]}`)
})
显然获取蔬菜数量vegetables[key]
ts语法检测报错,原因很简单,Object.keys(obj)
返回的是一个string[]
类型,然而vegetables
里面 的key值是"tomatoes" | "radishs" | "cabbages"
,string[] > "tomatoes" | "radishs" | "cabbages"
,类型定义的超出了他的可使用范围,所以最合适的办法就是,我们全局定义一个通用的获取Object.key的方法,让他返回对象key值的联合类型的数组,具体如下:
const vegetables = {
tomatoes: 12,
radishs: 10,
cabbages: 1
}
export const getObjectKey = <T>(obj: T): (keyof T)[] => {
return Object.keys(obj) as (keyof T)[]
}
getObjectKey(vegetables).forEach((key) => {
console.log(`${key}-数量-${vegetables[key]}`)
})
看看实际效果,很清爽的提示~
(4)、Pick 让类型可以复用
在实际项目中,我们有时候后需要从一个已知的类型中生成一个子集内容来使用,如下所示:
interface Info {
name: string
age: number
addr: string
phoneNum: number
hobby: string
}
interface PersonHobby {
name: string
hobby: string
}
这种写法当然是没有问题的,当然不是最高明的写法,我们可以通过ts提供的Pick类型函数进行改造,具体如下:
interface Info {
name: string
age: number
addr: string
phoneNum: number
hobby: string
}
interface PersonHobby {
name: string
hobby: string
}
type NewPersonHobby = Pick<Info, 'name' | 'hobby'>
对比一下,用一行代码解决了四行代码做的事儿,是不是显得你很帅~
(5)、关于react中的组件类型获取办法
react项目,我们使用antd组件库,定义组件方法是不是经常command
进去查阅类型定义,然后复制引入一些类型定义复杂的方式,最后满足了类型校验,最后一看代码一坨~
import React from 'react'
import { Table, TablePaginationConfig } from 'antd'
import { FilterValue, SorterResult, TableCurrentDataSource } from 'antd/lib/table/interface'
const Demo: React.FC = () => {
const onTableChange = (
pagination: TablePaginationConfig,
filters: Record<string, FilterValue | null>,
sorter: SorterResult<any> | SorterResult<any>[],
extra: TableCurrentDataSource<any>
) => {
console.log(pagination, filters, sorter, extra)
}
return <Table dataSource={[]} onChange={onTableChange}></Table>
}
那么我们又什么简单方法么?当然有,之前我也是按照这样的笨方法去做的,直到有一天发现了React.ComponentProps
这个工具函数,翻生码农把歌唱~,走一波
import React from 'react'
import { Table } from 'antd'
const Demo: React.FC = () => {
const onTableChange: React.ComponentProps<typeof Table>['onChange'] = (pagination, filters, sorter, extra) => {
console.log(pagination, sorter, filters, extra)
}
return <Table dataSource={[]} onChange={onTableChange}></Table>
}
通过这样的方式是不是简单很多,也无需balabala引入一堆东西来去做~~
本期我就先写这些项目上常使用的一些ts类型技巧,喜欢的朋友们,可以点赞、收藏、关注三连走一波,感谢感谢~
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)