keyof
类似于Object.keys(),用于把interface的所有key以“或”的形式组成一个新的类型,类似于枚举类型
interface Point {
x: number;
y: number;
}
type PointKeys = keyof Point
const key: PointKeys = 'x' // key只能赋值'x'或者'y'
实例:实现一个get函数来获取object的属性值
function get<T extends Record<string, unknown>, K extends keyof T>(obj: T, key: K): T[K]{
return obj[key]
}
// 提示:使用Record<string, unknow>代替object
Record
上面用到了Record,那么就先来看它吧,通常用在声明对象时进行类型指定,第一个参数是key的类型,第二个参数是值得类型。
const obj: Record<string, string> = {
name: 'lisa'
}
Record实现:这里又用到了keyof
type Record<K extends keyof any, T> = {
[P in K]: T
}
in
Record的实现中用到了in,in是与keyof相对应的,keyof是产生枚举类型,通过in可以遍历枚举类型
type Keys = 'a' | 'x' | 'y'
type Obj = {
[k in Keys]: unknow
}
==相当于==> {a: unknow, x: unknow, y: unknow}
实例:提前看一下Partial源码
type Partial<T> = {
[K in keyof T]?: T[K]
}
const obj: Partial<Point> = {
x: 1,
y: 1
}
// 因为obj类型相当于{x?: number, y?: number}
Partial / Required / Readonly
说到Partial,从源码可以看出Partial用来将类型的所有属性变为可选属性。
与其对应的还有Required(将所有属性变成必选)
type Required<T> = {
[K in keyof T]: T[K]
}
Readonly比较简单,就是把所有属性变成只读属性
type C = {
x?: string
y: string
z: string
}
type aa = Readonly<C>
// 以上相当于:
type aa = {
readonly x?: string;
readonly y: string;
readonly z: string;
}
实现:
type Readonly<T> = {
readonly[K in keyof T]: T[K]
}
Pick / Omit
Pick:从接口中挑拣选择部分属性作为新的类型,第一个参数:原接口类型,第二个参数:要选择的属性
type obj = {
a: number,
b: number,
x: number
}
const aa: Pick<obj, 'a'> = {
a: 1, // 只能有a属性
}
实现:
type Pick<T, K extends keyof T> = {
[P in K]: T[K]
}
Omit的作用是从接口中,忽略排除部分属性作为新的类型。这里使用到了Exclude。如下:变量aa使用Omit声明类型,结果为obj中除了'a'和'x',剩下属性=>{b: number}
type obj = {
a: number,
b: number,
x: number
}
const aa: Omit<obj, 'a' | 'x'> = {
b: 1,
}
实现:
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
Exclude / Extract
Exclude字面意思就是“排除”,从第一个参数类型中排除第二个参数中有的类型。
type A = 'x' | 'y'
type B = 'x' | 'y' | 'z'
type Oo = Exclude<B, A>
const str: Oo = 'z' // B的z类型在A中没有,所以Exclude<B, A>就相当于'z'
// const str: Oo = 'x' // 不可以赋值
实现:
type Exclude<T, U> = T extends U ? never T
Extract和Exclude相对应,用于取交集,即两者都有的类型
type Ex = Extract<'id'|'name'|'age', 'id'|'ho'>
const obj: Ex = 'id'
const obj: Ex = 'ho' //报错
实现:
type Exclude<T, U> = T extends U ? T : never
NonNullable
把联合类型中的null和undefined去掉之后的新类型
type Test = number | null | undefined
type Non = NonNullable<Test> // 等价于 type Non = number
实现:
type NonNullable<T> = T extends null | undefined ? never T
is类型保护
使用is可以做类型的保护,常见实例如,isXXX函数,判定一个变量是不是指定类型。
function isStr(val: unknown): val is string {
return typeof val === 'string'
}
function fn(value: unknown){
if(isStr(value)){
console.log(value.length) // 这里value已经判定为string类型,所有不会报错
}
}
fn(12)
如果不使用is,直接使用boolean
function isStr(val: unknown): boolean {
return typeof val === 'string'
}
function fn(value: unknown){
if(isStr(value)){
console.log(value.length) // 这里会报错,因为value可能是unknow类型
}
}