🤪🤪TS高级用法(一)
站长
· 阅读数 18
如今,越来越多的项目使用了TypeScript
进行编写,我们都知道TypeScript
是JavaScript
的超集,它为JavaScript
提供了强大的类型和语法增强功能,能在项目开发的过程中大大减少错误的产生。而TypeScript
也内置了很多的工具类型,接下来,我将带着大家学习TypeScript
中的工具类型。
本文中为系列文章的第一篇
Partial
Partial
用于将一个类型中的所有属性转变为可选属性。
栗子
interface PhoneType {
width: number;
height: number;
}
const D1:PhoneType={
width:100,
height:100
}
// 错误, 缺少height属性
const D2:PhoneType={
width:100,
}
// 此时,weight和height变为可选属性
// type Partial<T> = { [P in keyof T]?: T[P]; }
const D3:Partial<PhoneType>={
width:100,
}
分析
可以看到,Partial
会将我们传入的类型先通过keyof
获取对应的属性名称,在进行遍历,将对应属性类型赋值给P
,使用可选的符号?
,让属性成为可选属性。
type Partial<T> = { [P in keyof T]?: T[P]; }
Required
Required
,从名称上我们就可以猜测到,它是一个将一个类型中所有属性转变为必选属性的方法。
栗子
interface PersonType {
name: string;
age?: number;
}
// 正常情况下,age属性可不填写
const p1: PersonType = {
name: "_island",
};
// 错误,缺少age属性
// 类型 "{ name: string; }" 中缺少属性 "age",但类型 "Required<PersonType>" 中需要该属性。ts(2741)
const p2: Required<PersonType> = {
name: "zhangsan",
};
// type Required<T> = { [P in keyof T]-?: T[P]; }
// 将age属性变成必选属性
const p3: Required<PersonType> = {
name: "lisi",
age: 18,
};
分析
同上面的Partial
一样,先通过keyof
获取类型中的属性名称,进行遍历操作。这里不同的是在?前面多出了-
,意思是将可选属性的?
符号去掉,变为必选属性。
type Required<T> = { [P in keyof T]-?: T[P]; }
Pick
Pick
用于从一个类型中,提取一个或者多个属性出来。
栗子
interface HousesItemType {
desc: string;
houseCode: string;
houseImg: string | string[];
price: number | string;
tags: string[];
title: string;
}
// type Pick<T, K extends keyof T> = { [P in K]: T[P]; }
// 从 HousesItemType 类型中提取出 houseCode houseImg price
type MiniHousesItemType = Pick<
HousesItemType,
"houseCode" | "houseImg" | "price"
>;
const item: MiniHousesItemType = {
houseCode: "39cadd9a",
houseImg: "file_path",
price: "1000",
};
分析
这个就很简单了,Pick
接受两个参数,从第一个参数类型中抽取第二个参数中类型属性。
type Pick<T, K extends keyof T> = { [P in K]: T[P]; }
Readonly
Readonly
用于将一个类型中的属性转换为可读属性,也即是后续不能修改这些属性值。
栗子
interface ResultType<T=any>{
data:T
status:number
}
const res:ResultType<string>={
data:'ok',
status:200
}
res.data='ook!'
// res --> ook!
const res2:Readonly<ResultType<string>>={
data:'ok',
status:200
}
// 无法赋值,data是只读属性
// type Readonly<T> = { readonly [P in keyof T]: T[P]; }
res2.data='ook!'
ReadonlyArray
const arr1:Readonly<number[]>=[1,2,3,4,5,6,7,8,9]
// 相当于上面的写法
const arr2:ReadonlyArray<number>=[1,2,3,4,5,6,7,8,9]
分析
Readonly
会将我们传入的类型先通过keyof
获取对应的属性名称,在进行遍历,将对应属性类型赋值给P
,使用Readonly
操作符,让其属性转变为可读属性。
type Readonly<T> = { readonly [P in keyof T]: T[P]; }
Record
Record
,翻译过来即是记录的意思,用于将一个类型中的属性值映射到另外一个类型。
栗子
interface PersonType {
name: string;
age?: number;
}
type Names = "_island" | "zhangsan" | "lisi";
// 将Names作为list的属性名称,PersonType作为属性值类型
// type Record<K extends string | number | symbol, T> = { [P in K]: T; }
const list: Record<Names, PersonType> = {
_island: { age: 10, name: "_island" },
zhangsan: { age: 5, name: "zhangsan" },
lisi: { age: 16, name: "lisi" },
};
分析
我们可以看到,将K(K只能是string
number
symbol
类型)转化作为T类型。
type Record<K extends string | number | symbol, T> = { [P in K]: T; }