本篇将介绍在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. ruby中的回调方法和钩子方法

    在ruby中,当某些特定的事件发生时,将调用回调方法和钩子方法.事件有如下几种: 调用一个不存在的对象方法 类混含一个模块 定义类的子类 给类添加一个实例方法 给对象添加一个单例方法 引用一个不存在的 ...

  2. hdu5021 树状数组+二分

    这 题 说 的 是 给 了 一 个 K—NN    每次查询离loc 最近的k个数 然后将这k个数的权值加起来除以k 赋值给 loc 这个位置上的 权值  我说说 我的做法 假如 查询的是loc 这个 ...

  3. ZLYD团队第5周项目总结

    ZLYD团队第5周项目总结 项目进展 目前游戏人没有成功运行.初步判断是部分代码有误. 我们采用了两种运行方式,代码未出现明确错误.但问题可能是由于版本问题. 将Wall.java.Gold.java ...

  4. 想转行学Java,却又担心自己半路出家成不了大牛

    想转行学Java,却又担心自己半路出家成不了大牛 很多人看好Java编程的高薪前景,在自己职业生涯迷茫的时候,想转行学Java,却又担心自己半路出家成不了大牛,赚不到钱,本文就为大家分析一下,转行学J ...

  5. [BZOJ1901]Dynamic Rankings

    Description 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1 ],a[i+2]……a[j]中第k小的数 ...

  6. Linux环境下如何配置IP地址、MAC地址

    Linux环境下如何配置IP地址.MAC地址 1.配置IP地址 进入配置IP地址路径,进行修改即可 cd /etc/network vim interface 加入以下内容: iface eth0 i ...

  7. js 判断浏览器类型及版本

    1.思路: 能力检测 + 字符串检索 2.例子 IE    Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)      ActiveXObject函 ...

  8. nodejs项目的model操作mongo

    想想以前学习hibernate的时候,学习各种表和表之间的映射关系等一对多,多对一,多对多,后来到了工作中,勇哥告诉我, 那时在学习的时候,公司中都直接用外键关联. 这里我们学习下,如何在Nodejs ...

  9. MySQL —— 基本查询方法

    MySQL —— 简单查询与按条件查询 在MySQL中从数据表中查询数据的基本语句时select语句.  select语句基本语法格式:      select 查询内容       from 表名  ...

  10. 何时使用MQ ?

    何时使用MQmq作为一种基础中间件在互联网项目中有着大量的使用. 一种技术的产生自然是为了解决某种需求,通常来说是以下场景: 需要跨进程通信:B系统需要A系统的输出作为输入参数.当A系统的输出能力远远 ...