学会了规则,表示你能使用 TypeScript。理解了类型推导,你才能成为 TypeScript 高手。

当我想要声明一个变量为 number 类型时,常规的语法是这样的

code.ts
let a: number = 20

我会明确指定变量 a 的类型。

但是如果我们理解了类型推导,就知道,这样的做法看上去就不太专业。

数字 20 在类型推导的机制下,会被判定为一个 number 类型,因此当我们将 20 赋值给变量 a 时,a 的类型也就确定下来了,就是 number

因此,在 ts 中,一个更专业的写法,就是

code.ts
let a = 20

当我们试图将别的类型赋值给 a 时,同样会抛出错误提示

我们可以继续观察几个被推导出来之后的结果

code.ts
let arr = [1, 2, 3, null]

函数也可以被推导

code.ts
1
function add(a = 0, b = 0) {
2
return a + b
3
}

复杂数据类型也可以

code.ts
1
const person = {
2
name: 'TOM',
3
age: 20,
4
gender: 1,
5
run: () => {}
6
}

再看看我们熟悉的 map 方法。

code.ts
1
const arr = [1, 2, 3, 4, 5]
2
const arr2 = arr.map((item) => {
3
return item + 1
4
})

当我们如此使用之后,会发现毫无 ts 痕迹。可是,该有的类型全都推导出来了。

数组的 map 方法能够做到这样的推导,得益于底层的 ts 声明。

code.ts
1
interface Array<T> {
2
map<U>(callbackfn: (value: T, index: number, array: T[]) => U): U[]
3
}

从声明中我们看出,callback 的第一个参数为泛型 T,即原数组的每一项的类型。而最后的返回结果 arr2 ,也是得益于泛型 U 的声明。

体会一下。

我们自己也可以做一些底层封装,让上层应用时变得更加简洁。

例如一个请求结果的封装

code.ts
1
// 底层声明
2
interface Result<T> {
3
code: number,
4
data: T,
5
success: boolean
6
}
7
8
// 底层封装
9
function get<T>(url: string) {
10
return new Promise<Result<T>>((resolve, reject) => {
11
})
12
}

一个返回 Promise 对象的 get 方法,此处唯一不能推导的就是 T,因此我们只需要在应用层,明确泛型变量 T 的类型即可,其他的全都通过推导搞定。

code.ts
1
interface User {
2
name: string,
3
id: string
4
}
5
6
// 应用层使用
7
function userListApi() {
8
return get<User[]>('xxxxx/api/user/list')
9
}

此时我们观察 useListApi 的类型结果,已经被完整的推导出来了。

类型推导还需要在实践中慢慢体会,运用了好,你们的 ts 会变得更加简洁。

专栏首页
到顶
专栏目录