ts 进阶版实战教程
鉴于很多小伙伴说前段时间出的 ts 教程
太过基础了,让我再出一期比较复杂的数据类型。今天就以我们平时开发过程中可能会遇到的类型简单讲解一下。
本期重点在后面的泛型,前面也是比较基础的。不想看的小伙伴可以直接定位拖到泛型的地方。
举例如下:
定义简单的基本数据类型:
const value:string = '北京'
const index:number = 1
const flag:boolean = false
定义复杂数据类型:
普通数组:
const strArr:string[] = ['0','1','2']
const numArr:number[] = [1,2,3]
包裹对象的数组:
const objArr:ObjArrType = [
{id:1,name:'小红',age:18}
]
这种数组就比上面两个数组复杂一些, 我们需要去单独定义一个类型。
type ObjArrType = {
id:number,
name:string,
age:number
}[]
树状数组:
const treeArr:TreeArr[] = [
{id:1,name:'小红',age:18,children:[
{
id:112,name:'小兰',age:23
}
]}
]
type TreeArr = {
id:number,
name:string,
age:number,
children?: TreeArr[]
}
对象:
const obj:{id:number,name:string,age:number} = {
id:112,name:'小兰',age:23
}
或者:
const obj:ObjType = {
id:112,name:'小兰',age:23
}
type ObjType = {
id:number,
name:string,
age:number
}
函数:
// 形参 返回值
const handle = (val:string):string=>{
return '1'
}
注意:如果定义返回值类型不为 void
或 any
, 必须 return 值
!
定义 useState
const [val, setVal] = useState<number>(1)
定义useState 的类型,需要使用到泛型,格式是 <类型>
。
说起泛型,也是我们日常工作中会经常用到的一个类型。这个类型也是比较麻烦的一个。下面我给大家简单的讲解一下:
泛型:
书写格式一般是用一对 <>
包裹起来的。 里面可以传入你需要的类型。
例如: <T>
, 这个 T, 就是你传入的类型,他可以是 string
, number
、boolean
、联合类型
、以及自己用 type
定义的类型。
我们可以使用 泛型
来创建可重用的组件,一个组件可以支持多种类型的数据。 这样就可以以自己的数据类型来使用组件。
例如:
function identity<T>(arg: T): T {
return arg;
}
这样,我们可以很清晰的知道,返回值和参数是一致的。我们把这个版本的identity
函数叫做泛型,因为它可以适用于多个类型
。
我们定义了泛型函数后,可以这样使用。传入所有的参数,包含类型参数:
let output = identity<string>("myString");
这里我们明确的指定了T
是string
类型,并做为一个参数传给函数。
再看下一个例子:
还是这个函数:
function identity<T>(arg: T): T {
return arg;
}
如果我们想同时打印出arg
的长度。 我们很可能会这样做:
function loggingIdentity<T>(arg: T): T {
console.log(arg.length); // Error: T doesn't have .length
return arg;
}
这里就会报错,说我们使用了arg
的.length
属性,但是没有地方指明arg
具有这个属性。这里的 T
代表的是任意类型,所以使用这个函数的人可能传入的是个数字,而数字是没有 .length
属性的。
所以,如果我们想操作T
类型的数组而不直接是T
, 可以这么写:
function loggingIdentity<T>(arg: T[]): T[] {
console.log(arg.length);
return arg;
}
我们可以这样理解这里的这个泛型T
。泛型函数loggingIdentity
,接收类型参数T
和参数arg
,这个参数 arg 它是个T
类型的数组,并返回元素类型是T
的数组,所以我们就可以很自然的打印 .lnegth
属性了。
再举个例子:
当我们发请求时,一般会封装一个请求函数,那这个请求函数的参数类型以及返回值类型怎么定义呢?
const getDateNumList = async (url: string, params?: ParamsType): Promise<ResultType<CardType>> => {
const { data } = await axiosInstance.post(`${url}`, params)
return data
}
参数类型相比不用我再多说了,url
是一个字符串类型,params
是一个我们自己定义的类型。关键是后面的返回值。有的小伙伴可能有点看不懂为什么这么写了。为什么泛型里面再套一个泛型,这个返回值是什么格式的呢?
我先把上面的返回值类型给拆分一下,类型一个一个的写出来:
export interface ResultType<T> {
code: string,
message: string,
data: T,
}
export type CardType = {
id?: number | undefined;
age?: number | undefined;
name?: string | undefined;
height?: number | undefined;
weight?: number |undefined;
}
可以看到,我们最外面是一个 Promise
类型, 他是一个泛型, 泛型内容写的是 ResultType
,也就是我们接口返回最外层的类型,有 code
、message
、data
。其中,data
也是一个泛型,用 T
来表示,就说明,这个 data
的类型,你传什么,他就是什么类型。
这里我们传的是 CardType
这个类型,那表示,最终 data
的类型就是 CardType
类型。
关于 interface
接口,我就不再细说了,不怎么会的小伙伴们可以看看前面的基础教程,里面有写,或者看看官网。
转载自:https://juejin.cn/post/7141281196813582367