ts高级使用一

1. keyofin

1.1 keyof

keyof 与 Object.keys 略有相似,只不过 keyof 取 interface 的键

1
2
3
4
5
6
7
interface Point {
x: number;
y: number;
}

// type keys = "x" | "y"
type keys = keyof Point;

js书写方式:

1
2
3
4
5
6
7
8
9
const data = {
a: 3,
hello: 'world'
}

function get(o: object, name: string) {
return o[name]
}
get(data,'a');

ts书写方式:

好处:

  1. 确认返回类型,增加ts 最大的类型校验功能
  2. key做约束,防止拼写错误的问题
1
2
3
function get<T extends object, K extends keyof T>(o: T, name: K): T[K] {
return o[name]
}

1.2 in

in 则可以遍历枚举类型

1
2
3
4
type Keys = "a" | "b"
type Obj = {
[p in Keys]: any
} // -> { a: any, b: any }

keyof 产生枚举类型,,in 使用枚举类型遍历

1
type Partial<T> = { [P in keyof T]?: T[P] };

keyof T 拿到 T 所有属性名,然后 in 进行遍历,将值赋给 P,最后 T[P] 取得相应属性的值

2. Required & Partial & Pick

Required必选

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type Required<T> = {
[P in keyof T]-?: T[P];//去掉可选
};
type User = {
name: string;
age?: number;
}

type newUser = Required<User>;
//等于
type newUser={
name: string;
age: number;
}

Partial可选

1
2
3
4
5
6
7
8
9
10
type Partial<T> = {
[P in keyof T]?: T[P]; //全部设置为可选
};
type User = {
name: string;
age?: number;
}
type PartialUser = Partial<User>
//等价
type PartialUser = { age?: number; name?: string; }

Pick指定属性必选

1
2
3
4
5
6
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
type PickUser = Pick<User, "id" | "age">
// 相当于
type PickUser = { id: number; age: number; }

Omit 可选属性

1
2
3
4
5
6
type Omit <T, K extends keyof T> = {
[P in K]?: T[P];
};
type PickUser = Omit<User, "id" | "age">
// 相当于
type PickUser = { id?: number; age?: number; }

3 其它

UnwrapRef

UnwrapRef类型,就是对Ref类型就行反解,其作用分为:

a.如果泛型T是Ref类型,则UnwrapRef类型为ref.value的类型(R)

b.如果泛型T不是Ref类型,则UnwrapRef类型为T

1
type UnwrapRef<T> = T extends ShallowRef<infer V> ? V : T extends Ref<infer V> ? UnwrapRefSimple<V> : UnwrapRefSimple<T>;

4. Condition Type

类似于 js 中的 三目 运算符,可以使用它扩展一些基本类型

1
2
3
4
5
6
7
8
9
T extends U ? X : Y

type isTrue<T> = T extends true ? true : false

// 相当于 type t = false
type t = isTrue<number>

// 相当于 type t = false
type t1 = isTrue<false>

5. never & Exclude & Omit

1
2
3
4
type Exclude<T, U> = T extends U ? never : T;

// 相当于: type A = 'a'
type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'>

结合 Exclude 可以推出 Omit 的写法

1
2
3
4
5
6
7
8
9
10
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

interface User {
id: number;
age: number;
name: string;
};

// 相当于: type PickUser = { age: number; name: string; }
type OmitUser = Omit<User, "id">

6. interface & type的区别

共同点:都是用来定义对象或函数的形状。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface example {
name: string
age: number
}

interface exampleFunc {
(name:string,age:number): void
}


type example = {
name: string
age: number
}

type example = (name:string,age:number) => { }

interface是通过extends实现的,type是通过&实现的。 其中 interface 可以如下合并多个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
type aa = {
name: string
}

interface bb {
name: string
}


type cc = aa & {
age: number
}

type cc = bb & {
age: number
}

interface dd extends aa {
age: number
}

interface dd extends bb {
age: number
}

type和interface的不同点

typeof

  • type可以定义 基本类型的别名,如 type myString = string

  • type可以通过 typeof 操作符来定义,如 type myType = typeof someObj

  • type可以申明 联合类型,如 type unionType = myType1 | myType2

  • type可以申明 元组类型,如 type yuanzu = [myType1, myType2]

interface可以 声明合并,这种情况下,如果是type的话,就会报 重复定义 的警告,因此是无法实现 声明合并 的。

interface test {
    name: string
}
 
interface test {
    age: number
}

/*
    test实际为 {
        name: string
        age: number
    }
*/

7 TS提供了几种内置的预定义的条件类型

  • Exclude<T, U> - 用于从类型T中去除不在U类型中的成员
  • Extract<T, U> - 用于从类型T中取出可分配给U类型的成员
  • NonNullable - 用于从类型T中去除undefined和null类型
  • ReturnType - 获取函数类型的返回类型
  • InstanceType - 获取构造函数的实例类型

ts高级使用一
https://leellun.github.io/2022/12/01/前端/2022-12-01-ts高级使用一/
作者
leellun
发布于
2022年12月1日
许可协议