本篇将介绍在TypeScript如何使用泛型。

一、泛型方法

在TypeScript里,声明泛型方法有以下两种方式:

 function generics_func1<T>(arg: T): T {
return arg;
}
// 或者
let generics_func2: <T>(arg: T) => T = function (arg) {
return arg;
}

调用方式也有两种:

 generics_func1<string>('Hello world');
// 或者
generics_func2('Hello world');

第二种调用方式可以省略类型参数,因为编译器会根据传入参数来自动识别对应的类型。

在之前介绍的基本类型里,有一个any类型,表示不确定的类型。在具体使用时,可以代替任意类型,比如如下方法定义和实现:

 function any_func(arg: any): any {
return arg;
} any_func(1);
any_func('Hello world!');
any_func(['1', '2']);

看似与泛型方法类似,但是还是有区别的。比如如下例子:

 // 方法一:带有any参数的方法
function any_func(arg: any): any {
console.log(arg.length);
return arg;
} // 方法二:Array泛型方法
function array_func<T>(arg: Array<T>): Array<T> {
console.log(arg.length);
return arg;
}

在方法一的方法体里,打印了arg参数的length属性。因为any可以代替任意类型,所以该方法在传入参数不是数组或者带有length属性对象时,会抛出异常。而方法二定义了参数类型是Array的泛型类型,肯定会有length属性,所以不会抛出异常。

从上面这个例子可以看出,泛型类型相比较any类型来说,在某些情况下会带有类型本身的一些信息,而any类型则没有。

二、泛型类

以下是一个泛型类的定义和调用

 class Generics_Demo<T>{
value: T;
show(): T {
return this.value;
}
} let gene_demo1 = new Generics_Demo<number>();
gene_demo1.value = 1;
console.log(gene_demo1.show()); // 调用方法 gene_demo1.show = function () { return gene_demo1.value + 1; } // 赋值新方法,返回值类型必须是number
console.log(gene_demo1.show());

通过指定明确类型的泛型类的实例,对属性赋值时,必须满足实际类型的约束。

三、泛型类型

以下几个例子都是利用泛型类型定义变量或者方法参数的类型的示例

1. 泛型接口

 interface Generics_interface {
<T>(arg: T): T;
} function func_demo<T>(arg: T): T {
return arg;
} let func1: Generics_interface = func_demo;

上面的例子里,接口只有一个泛型方法成员。则用此接口类型定义的变量就是一个与成员类型一致的泛型方法。

将上面例子的泛型接口稍微改一下

 interface Generics_interface<T> {
(arg: T): T;
} function func_demo<T>(arg: T): T {
return arg;
} let func1: Generics_interface<number> = func_demo;
func1(123); // 正确类型的实际参数
func1('123'); // 错误类型的实际参数

通过在接口上声明泛型,声明变量时明确指定泛型的具体类型,则赋值的方法将自动带上具体的类型约束。

2. 泛型类型继承

 interface LengthInterface {
length: number;
} function func_demo<T extends LengthInterface>(arg: T): T {
console.log(arg.length);
return arg;
} func_demo({ a: 1, length: 2 }); // 含有length属性的对象
func_demo([1, 2]); // 数组类型

上面的例子里,泛型类型继承自一个拥有length属性成员的接口,泛型类型将自动加上length属性的约束。调用时只有符合条件的对象才能正确赋值。

 function copy<T extends U, U>(source: U, target: T): T {
for (let prop in source) {
target[prop] = source[prop];
} return target;
} copy({ a: 1, b: 2 }, { a: 2, b: 3, c: 4 }); // 正确的实际参数
copy({ a: 1, b: 2 }, { q: 2, c: 4 }); // 错误的实际参数

在上面的例子里,一个泛型类型继承自另外一个泛型类型。在方法调用时,就必须确保继承类型对应的参数对象属性完全包含被继承类型对应的参数对象。

TypeScript学习笔记(五) - 泛型的更多相关文章

  1. Typescript 学习笔记五:类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  2. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  3. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  4. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  5. Typescript 学习笔记二:数据类型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  6. Typescript 学习笔记三:函数

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  7. Typescript 学习笔记一:介绍、安装、编译

    前言 整理了一下 Typescript 的学习笔记,方便后期遗忘某个知识点的时候,快速回忆. 为了避免凌乱,用 gitbook 结合 marketdown 整理的. github地址是:ts-gitb ...

  8. C#可扩展编程之MEF学习笔记(五):MEF高级进阶

    好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...

  9. (转)Qt Model/View 学习笔记 (五)——View 类

    Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...

  10. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

随机推荐

  1. 154. Find Minimum in Rotated Sorted Array II(剑指offer)

    Follow up for "Find Minimum in Rotated Sorted Array":What if duplicates are allowed? Would ...

  2. BUG克星:几款优秀的BUG跟踪管理软件

    Bug管理是指对开发,测试,设计等过程中一系列活动过程中出现的bug问题给予纪录.审查.跟踪.分配.修改.验证.关闭.整理.分析.汇总以及删除等一系列活动状态的管理.,最后出相应图表统计,email通 ...

  3. VS2010/MFC编程入门之前言

    鸡啄米的C++编程入门系列给大家讲了C++的编程入门知识,大家对C++语言在语法和设计思想上应该有了一定的了解了.但是教程中讲的例子只是一个个简单的例程,并没有可视化窗口.鸡啄米在这套VS2010/M ...

  4. MapReduce: map读取文件的过程

    我们的输入文件 hello0, 内容如下: xiaowang 28 shanghai@_@zhangsan 38 beijing@_@someone 100 unknown 逻辑上有3条记录, 它们以 ...

  5. Flex与SSH集成

    Flex与SSH集成 -- ::| 分类: flex |举报|字号 订阅 Flex与SSH集成 ,下载blazeds_bin_3---.zip 包,将其解压 取下blazeds.war包 更改为bla ...

  6. 【运维技术】CentOS7上从零开始安装阿里RocketMQ版本:release-4.0.1【亲测哈哈】

    CentOS7上从零开始安装阿里RocketMQ版本:release-4.0.1[亲测哈哈] 安装git # 更新包 $ yum update # 安装git $ yum install git # ...

  7. 【转载】make: Nothing to be done for `all'. 解决方法

    转自:make: Nothing to be done for `all'.解决方法 make: Nothing to be done for `all' 解决方法 1.这句提示是说明你已经编译好了, ...

  8. [BZOJ4069][Apio2015]巴厘岛的雕塑

    题目大意 分成 \(x\) 堆,是的每堆的和的异或值最小 分析 这是一道非常简单的数位 \(DP\) 题 基于贪心思想,我们要尽量让最高位的 \(1\) 最小, 因此我们考虑从高位向低位进行枚举,看是 ...

  9. 科幻小说《霜与火》 by 雷·布雷德伯里

    漫漫长夜中,西姆出世了,躺在山洞冰凉的石头上,嗷嗷大哭,浑身血液奔流,脉搏每分钟一千跳.他不停地长大.妈妈用发烫的双手喂西姆吃东西.人生的梦魔开场了.一来到世间,他的眼睛就闪烁着警觉的光芒:而后又令人 ...

  10. POJ Stockbroker Grapevine(floyd)

    https://vjudge.net/problem/POJ-1125 题意: 题意不是很好理解,首先输入一个n,表示有n个股票经纪人,接下来输入n行,每行第一个数m为该股票经纪人认识的经纪人数,然后 ...