网站建设岗位招聘,为什么做美妆网站,提供邯郸移动网站建设,网站建设基本范例【TypeScript学习之路】泛型 文章目录【TypeScript学习之路】泛型写在前面前言一、认识泛型1.1 什么是泛型1.2 泛型函数的使用二、泛型接口与泛型类2.1 泛型接口2.2 泛型类三、泛型约束写在前面 #x1f917;这里是前端程序员小张#xff01; #x1f33b;人海茫茫#xff…【TypeScript学习之路】泛型 文章目录【TypeScript学习之路】泛型写在前面前言一、认识泛型1.1 什么是泛型1.2 泛型函数的使用二、泛型接口与泛型类2.1 泛型接口2.2 泛型类三、泛型约束写在前面 这里是前端程序员小张 人海茫茫感谢这一秒你看到这里。希望我的文章对你的有所帮助 愿你在未来的日子保持热爱奔赴山海 前言 软件工程中我们不仅要创建一致的定义良好的API同时也要考虑可重用性。 组件不仅能够支持当前的数据类型同时也能支持未来的数据类型这在创建大型系统时为你提供了十分灵活的功能。 在像C#和Java这样的语言中可以使用泛型来创建可重用的组件一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。 一、认识泛型
1.1 什么是泛型
软件工程的主要目的是构建不仅仅明确和一致的API还要让你的代码具有很强的可重用性
比如我们可以通过函数来封装一些API通过传入不同的函数参数让函数帮助我们完成不同的操作但是对于参数的类型是否也可以参数化呢 什么是类型的参数化 我们来提一个需求封装一个函数传入一个参数并且返回这个参数
//TypeScript的思维方式要考虑这个参数和返回值的类型需要一致
function fn(arg: number): number {return arg;
}上面的代码虽然实现了但是不适用于其他类型比如string、boolean、自定义类等类型
function fn(arg: any): any {return arg;
}使用any类型会导致这个函数可以接收任何类型的arg参数这样就丢失了类型信息
传入的类型与返回的类型应该是相同的。如果我们传入一个数字我们只知道任何类型的值都有可能被返回。
因此我们需要一种方法使返回值的类型与传入参数的类型是相同的。 这里我们使用了 类型变量它是一种特殊的变量只用于表示类型而不是值。
function fnType(arg: Type): Type {return arg;
}我们给 fn 添加了类型变量Type。Type帮助我们捕获用户传入的类型比如number之后我们就可以使用这个类型。 之后我们再次使用了 Type当做返回值类型。现在我们可以知道参数类型与返回值类型是相同的了。 这允许我们跟踪函数里使用的类型的信息。 我们把这个版本的fn函数叫做泛型因为它可以适用于多个类型。 不同于使用 any它不会丢失信息像第一个例子那像保持准确性传入数值类型并返回数值类型。 1.2 泛型函数的使用
我们定义了泛型函数后可以用两种方法使用。
通过 类型 的方式将类型传递给函数
fnstring(hello world)
fnnumber(123)通过类型推导type argument inference自动推到出我们传入变量的类型 在这里会推导出它们是 字面量类型的因为字面量类型对于我们的函数也是适用的
let message1 fn(hello world)
let message2 fn(123)当然我们也可以传入多个类型
function fnT, E(a1: T, a2: E) {}平时在开发中我们可能会看到一些常用的名称
TType的缩写类型K、Vkey和value的缩写键值对EElement的缩写元素OObject的缩写对
二、泛型接口与泛型类
2.1 泛型接口
在定义接口的时候我们也可以使用泛型
我们可能想把泛型参数当作整个接口的一个参数这样我们就能清楚的知道使用的具体是哪个泛型类型这样接口里的其它成员也能知道这个参数的类型了
interface IFnT {(arg: T): T;
}function fnT(arg: T): T {return arg;
}let myFn: IFnnumber fn;当我们使用 IFn的时候还得传入一个类型参数来指定泛型类型这里是number锁定了之后代码里使用的类型。
2.2 泛型类
泛型类看上去与泛型接口差不多。 泛型类使用 括起泛型类型跟在类名后面。
class PointT {x: T;y: T;constructor(x: T, y: T) {this.x x;this.y y;}
}const p1 new Point(10, 20);
const p2 new Pointnumber(20, 30);
const p3: Pointnumber new Point(40, 60);三、泛型约束
我们有时候想操作某类型的一组值并且我们知道这组值具有什么样的属性 我们希望传入的类型有某些共性但是这些共性可能不是在同一种类型中 在上述例子中我们想访问arg的length属性但是编译器并不能证明每种类型都有length属性所以就报错了 比如string和array都是有length的或者某些对象也是会有length属性的 那么只要是拥有length的属性都可以作为我们的参数类型那么应该如何操作呢为此我们需要列出对于T的约束要求。
我们定义一个接口来描述约束条件。 创建一个包含 .length属性的接口使用这个接口和extends关键字来实现约束
interface TLength {length: number;
}function getLengthT extends TLength(args: T) {return args.length;
}现在这个泛型函数被定义了约束因此它不再是适用于任意类型
getLength(3) // Argument of type number is not assignable to parameter of type ILength.我们需要传入符合约束类型的值
console.log(getLength(hello))
console.log(getLength([abe, de]))
console.log(getLength({length: 10, name: zhang}))