当前位置: 首页 > news >正文

TypeScript学习笔记(六):泛型

认识泛型

TypeScript也实现了类型于C#和Java的泛型以实现类型的参数化,我们先看一个需求:

1 function identity(arg: any): any {
2     return arg;
3 }

我们希望方法identity可以传入任意类型,并且返回传入的类型,这样写可以达到效果但是不能确定返回的类型,使用泛型的写法如下:

复制代码
1 function identity<T>(arg: T): T {
2     return arg;
3 }
4 
5 var output = identity<string>("myString");  // type of output will be 'string'
6 var output = identity("myString");  // type of output will be 'string'
复制代码

我们可以指定类型,也可以让编译器自动来识别类型。

泛型数组

我们也可以通过泛型来指定一个数组,写法如下:

复制代码
1 function loggingIdentity<T>(arg: T[]): T[] {
2     console.log(arg.length);  // Array has a .length, so no more error
3     return arg;
4 }
5 
6 function loggingIdentity<T>(arg: Array<T>): Array<T> {
7     console.log(arg.length);  // Array has a .length, so no more error
8     return arg;
9 }
复制代码

泛型类型

我们可以指定一个带有泛型的函数:

1 function identity<T>(arg: T): T {
2     return arg;
3 }
4 
5 var myIdentity: <U>(arg: U)=>U = identity;

还有另一种写法:

1 function identity<T>(arg: T): T {
2     return arg;
3 }
4 
5 var myIdentity: {<T>(arg: T): T} = identity;

使用函数接口的写法如下:

复制代码
1 interface GenericIdentityFn {
2     <T>(arg: T): T;
3 }
4 
5 function identity<T>(arg: T): T {
6     return arg;
7 }
8 
9 var myIdentity: GenericIdentityFn = identity;
复制代码

同时泛型还可以作为类型的参数而不是方法的参数,写法如下:

复制代码
1 interface GenericIdentityFn<T> {
2     (arg: T): T;
3 }
4 
5 function identity<T>(arg: T): T {
6     return arg;
7 }
8 
9 var myIdentity: GenericIdentityFn<number> = identity;
复制代码

泛型类

泛型除了可以用在接口上以外,当然还可以用在类上:

复制代码
 1 class GenericNumber<T> {
 2     zeroValue: T;
 3     add: (x: T, y: T) => T;
 4 }
 5 
 6 var myGenericNumber = new GenericNumber<number>();
 7 myGenericNumber.zeroValue = 0;
 8 myGenericNumber.add = function(x, y) { return x + y; };
 9 
10 var stringNumeric = new GenericNumber<string>();
11 stringNumeric.zeroValue = "";
12 stringNumeric.add = function(x, y) { return x + y; };
13 alert(stringNumeric.add(stringNumeric.zeroValue, "test"));
复制代码

使用方法和C#与Java一致。

泛型约束

之前的泛型可以是任意的类型,我们还可以约束泛型的类型,我们先看一个会报错的例子:

1 function loggingIdentity<T>(arg: T): T {
2     console.log(arg.length);  // Error: T doesn't have .length
3     return arg;
4 }

报错原因是,类型T没有length属性,我们可以为类型T指定一个类型,如下:

复制代码
1 interface Lengthwise {
2     length: number;
3 }
4 
5 function loggingIdentity<T extends Lengthwise>(arg: T): T {
6     console.log(arg.length);  // Now we know it has a .length property, so no more error
7     return arg;
8 }
复制代码

写法是通过extends来指定类型T的类型必须是实现了Lengthwise接口的类型。

调用如下:

1 loggingIdentity(3);  // Error, number doesn't have a .length property
2 loggingIdentity({length: 10, value: 3});  

泛型约束泛型

某些情况下,我们可能会有如下的需求:

1 function find<T, U extends Findable<T>>(n: T, s: U) {   // errors because type parameter used in constraint
2   // ...
3 } 
4 find (giraffe, myAnimals);

这种写法会报错,可以使用下面正确的写法来达到效果:

1 function find<T>(n: T, s: Findable<T>) {   
2   // ...
3 } 
4 find(giraffe, myAnimals);

在泛型中使用类类型

有时我们希望可以指定泛型的构造函数和属性,写法如下:

1 function create<T>(c: {new(): T; }): T { 
2     return new c();
3 }

再看另外一个例子:

复制代码
 1 class BeeKeeper {
 2     hasMask: boolean;
 3 }
 4 
 5 class ZooKeeper {
 6     nametag: string; 
 7 }
 8 
 9 class Animal {
10     numLegs: number;
11 }
12 
13 class Bee extends Animal {
14     keeper: BeeKeeper;
15 }
16 
17 class Lion extends Animal {
18     keeper: ZooKeeper;
19 }
20 
21 function findKeeper<A extends Animal, K> (a: {new(): A; 
22     prototype: {keeper: K}}): K {
23 
24     return a.prototype.keeper;
25 }
26 
27 findKeeper(Lion).nametag;  // typechecks!
复制代码

转载于:https://www.cnblogs.com/lancidie/p/7344918.html

相关文章:

  • Unity3D之Mecanim动画系统学习笔记(十):Mecanim动画的资源加载相关
  • Android零基础入门第11节:简单几步带你飞,运行Android Studio工程
  • java中你确定用对单例了吗?
  • 深入分析Sleep(0)与Sleep(1)的区别
  • swift3.0常用操作包含删除字符串(string),更换字符串,插入字符串
  • 第21章 RTX 低功耗之睡眠模式
  • Spring思维导图(AOP篇)
  • layer close 关闭层IE9-浏览器崩溃问题解决
  • Java-static
  • 克隆用户过狗提权
  • Linux中如何查看显卡硬件信息
  • 搭建本地yum源服务器
  • Linux下NMAP常用扫描简介(一)
  • 利用Sympy计算sin1°的最小多项式
  • sql server2008 在window2012 R2安装集群注意事项
  • 08.Android之View事件问题
  • Apache Pulsar 2.1 重磅发布
  • Django 博客开发教程 8 - 博客文章详情页
  • Electron入门介绍
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • happypack两次报错的问题
  • js数组之filter
  • laravel5.5 视图共享数据
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • Node + FFmpeg 实现Canvas动画导出视频
  • php中curl和soap方式请求服务超时问题
  • python大佬养成计划----difflib模块
  • Python学习之路13-记分
  • rabbitmq延迟消息示例
  • rc-form之最单纯情况
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • 如何学习JavaEE,项目又该如何做?
  • 小试R空间处理新库sf
  • 学习HTTP相关知识笔记
  • 再次简单明了总结flex布局,一看就懂...
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ​​​​​​​​​​​​​​Γ函数
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (笔试题)合法字符串
  • (二)JAVA使用POI操作excel
  • (力扣题库)跳跃游戏II(c++)
  • (原)Matlab的svmtrain和svmclassify
  • (转)memcache、redis缓存
  • (转载)PyTorch代码规范最佳实践和样式指南
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具
  • [100天算法】-二叉树剪枝(day 48)
  • [android] 天气app布局练习
  • [bzoj1324]Exca王者之剑_最小割
  • [DevEpxress]GridControl 显示Gif动画