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

一、泛型方法

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

1 function generics_func1<T>(arg: T): T {
2     return arg;
3 }
4 // 或者
5 let generics_func2: <T>(arg: T) => T = function (arg) {
6     return arg;
7 }

调用方式也有两种:

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

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

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

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

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

 1 // 方法一:带有any参数的方法
 2 function any_func(arg: any): any {
 3     console.log(arg.length);
 4     return arg;
 5 }
 6
 7 // 方法二:Array泛型方法
 8 function array_func<T>(arg: Array<T>): Array<T> {
 9     console.log(arg.length);
10     return arg;
11 }

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

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

二、泛型类

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

 1 class Generics_Demo<T>{
 2     value: T;
 3     show(): T {
 4         return this.value;
 5     }
 6 }
 7
 8 let gene_demo1 = new Generics_Demo<number>();
 9 gene_demo1.value = 1;
10 console.log(gene_demo1.show());                                     // 调用方法
11
12 gene_demo1.show = function () { return gene_demo1.value + 1; }      // 赋值新方法,返回值类型必须是number
13 console.log(gene_demo1.show());

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

三、泛型类型

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

1. 泛型接口

1 interface Generics_interface {
2     <T>(arg: T): T;
3 }
4
5 function func_demo<T>(arg: T): T {
6     return arg;
7 }
8
9 let func1: Generics_interface = func_demo;

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

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

 1 interface Generics_interface<T> {
 2     (arg: T): T;
 3 }
 4
 5 function func_demo<T>(arg: T): T {
 6     return arg;
 7 }
 8
 9 let func1: Generics_interface<number> = func_demo;
10 func1(123);     // 正确类型的实际参数
11 func1('123');   // 错误类型的实际参数

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

2. 泛型类型继承

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

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

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

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

转载于:https://www.cnblogs.com/niklai/p/5794044.html

TypeScript学习笔记(五) - 泛型相关推荐

  1. Java核心技术【卷一】——学习笔记(五)--泛型(一)

    若要对某个特定类的特定关键字进行比较,可使用泛型来进行比较 若要对Student类的score字段进行比较,需要对Student implements Compareable接口 public cla ...

  2. Typescript 学习笔记七:泛型

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

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

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

  4. python函数是一段具有特定功能的语句组_Python学习笔记(五)函数和代码复用

    本文将为您描述Python学习笔记(五)函数和代码复用,具体完成步骤: 函数能提高应用的模块性,和代码的重复利用率.在很多高级语言中,都可以使用函数实现多种功能.在之前的学习中,相信你已经知道Pyth ...

  5. Ethernet/IP 学习笔记五

    Ethernet/IP 学习笔记五 Accessing data within a device using a non-time critical message (an explicit mess ...

  6. TypeScript学习笔记3:运算符

    TS 和 JS 相对比的优势 TypeScript的安装步骤.运行问题及代码的简单运行 TypeScript学习笔记1:变量赋值及书写方式 TypeScript学习笔记2:数据类型 文章目录 运算符 ...

  7. TypeScript学习笔记2:数据类型

    TS 和 JS 相对比的优势 TypeScript的安装步骤.运行问题及代码的简单运行 TypeScript学习笔记1:变量赋值及书写方式 TypeScript学习笔记2:数据类型 文章目录 数据类型 ...

  8. TypeScript学习笔记1:变量赋值及书写方式

    TS 和 JS 相对比的优势 TypeScript的安装步骤.运行问题及代码的简单运行 TypeScript学习笔记1:变量赋值及书写方式 TypeScript学习笔记2:数据类型 文章目录 变量赋值 ...

  9. StackExchange.Redis学习笔记(五) 发布和订阅

    StackExchange.Redis学习笔记(五) 发布和订阅 原文:StackExchange.Redis学习笔记(五) 发布和订阅 Redis命令中的Pub/Sub Redis在 2.0之后的版 ...

  10. 吴恩达《机器学习》学习笔记五——逻辑回归

    吴恩达<机器学习>学习笔记五--逻辑回归 一. 分类(classification) 1.定义 2.阈值 二. 逻辑(logistic)回归假设函数 1.假设的表达式 2.假设表达式的意义 ...

最新文章

  1. 附录7:SciPy实例记录
  2. 如何在Chatbot中应用深度学习
  3. junit 参数化测试用例_JUnit:在参数化测试中命名单个测试用例
  4. 【转】详细图解Vmware与主机间共享文件的方法
  5. 2017年给自己定个小目标!
  6. 【java与智能设备】01_2Android简介与环境搭建——开发环境
  7. Win10 桌面美化
  8. 安国主控au6983、au698x fc8708 量产失败修复过程。载入韧体数据失败\坏磁区过多\读坏块表错误...
  9. STM32(3)——外部中断的使用
  10. Unreal Engine 4 —— Smear Frame效果的实现与分析
  11. 代币标准--ERC721协议源码解析
  12. Linux一键脚本自动化安装项目环境
  13. C++ 与 elang 通信注意问题
  14. 多线程环境下HashMap导致CPU100%
  15. Javaweb-01.html和css
  16. Qt编写可视化大屏电子看板系统26-模块4模具进度
  17. 24部电影的人生哲理
  18. 华为云配置https访问
  19. Excel2016编辑和保存.bdf文件
  20. python 获取qq群成员信息_教你用python爬取自己加入的QQ群成员名单,它们竟然是这样的人...

热门文章

  1. Android深度探索-卷1第二章心得体会
  2. 【Acm】算法之美—Fire Net
  3. C\C++的转义字符
  4. onload、DOMContentLoaded、$(document).ready(fn)、$(document).load(fn)
  5. LeetCode(237)——删除链表中的节点(JavaScript)
  6. C++---const关键字
  7. VSCode打开底部状态栏
  8. volatile 关键字(详细讲解)
  9. Safari 是什么
  10. 地推HTTP3和QUIC