我们来看一下 TypeScript 中的泛型,这也是很多同学觉得 TypeScript 很难的最大原因。
首先我们看下面的代码,我们定一个 idientity0 函数,这个函数逻辑非常简单,就是直接返回参数,那么我们怎么确定返回值的类型呢?
因为输入值可以是任意属性,所以我们只能写出 identity0 这个函数,参数和返回值类型都是 any,但是明显不能满足我们的需求。我们需要返回值的类型和参数一致,所以我们在函数名之后使用 <> 定一个泛型 T,你可以理解这个 T 的意思就是给函数参数定义了一个类型变量,会在后面使用,相当于【type T = arg 的类型】,返回值使用 T 这个类型就完成了这个需求。
function identity0(arg: any): any {
return arg
}
// 相当于type T = arg的类型
function identity<T>(arg: T): T {
return arg
}
identity<string>('玩转vue 3全家桶') // 这个T就是string,所以返回值必须得是string
identity<number>(1)
有了泛型之后,我们就有了把函数参数定义成类型的功能,我们就可以实现类似高阶函数的类型函数。下面的代码中我们使用 keyof 语法获得已知类型 VueCourse5 的属性列表,相当于 ‘name’|‘price’:
interface VueCourse5 {
name:string,
price:number
}
type CourseProps = keyof VueCourse5 // 只能是name和price选一个
let k:CourseProps = 'name'
let k1:CourseProps = 'p' // 改成price
keyof 可以帮助我们拆解已有类型,下一步我们需要使用 extends 来实现类型系统中的条件判断。我们定义类型函数 ExtendsType,接受泛型参数 T 后,通过判断 T 是不是布尔值来返回不同的类型字符串,我们就可以通过 ExtendsType 传入不同的参数去返回不同的类型。
// T extends U ? X : Y 类型三元表达式
type ExtendsType<T> = T extends boolean ? "重学前端" : "玩转Vue 3"
type ExtendsType1 = ExtendsType<boolean> // type ExtendsType1='重学前端'
type ExtendsType2 = ExtendsType<string> // type ExtendsType2='玩转Vue 3'
extends 相当于 TypeScript 世界中的条件语句,然后 in 关键字可以理解为 TypeScript 世界中的遍历。下面的代码中我们通过 k in Courses 语法,相当于遍历了 Courses 所有的类型作为 CourseObj 的属性,值的类型是 number。
type Courses = '玩转Vue 3'|'重学前端'
type CourseObj = {
[k in Courses]:number // 遍历Courses类型作为key
}
// 上面的代码等于下面的定义
// type CourseObj = {
// 玩转Vue 3: number;
// 重学前端: number;
// }
学完上面的语法,你就能完全搞懂第 18 讲里的 getProperty 函数。限制函数第二个参数只能是第一个参数的属性,并且返回值的类型,最后我们传递不存在的属性时,TypeScript 就会报错。文章来源:https://www.toymoban.com/news/detail-534442.html
// K extends keyof T限制K的类型必须是T的属性之一
// T[K]是值得类型
function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
return o[name]
}
const coursePrice:CourseObj = {
"玩转Vue 3":129,
"重学前端":129
}
getProperty(coursePrice,'玩转Vue 3')
getProperty(coursePrice,'不学前端') // 报错
然后我再给你讲解最后一个关键字 infer。 让我们拥有了给函数的参数定义类型变量的能力,infer 则是可以在 extends 之后的变量设置类型变量,更加细致地控制类型。下面的代码中我们定义了 ReturnType 类型函数,目的是返回传入函数的返回值类型。infer P 的意思就是泛型 T 是函数类型,并且这个函数类型的返回类型是 P。文章来源地址https://www.toymoban.com/news/detail-534442.html
type Foo = () => CourseObj
// 如果T是一个函数,并且函数返回类型是P就返回P
type ReturnType1<T> = T extends ()=>infer P ?P:never
type Foo1 = ReturnType1<Foo>
到了这里,关于TypeScript 可以进行类型编程,这会极大提高 TypeScript 在复杂场景下的应用场景。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!