TypeScript 学习笔记(七):泛型

前言

在上一篇文章TypeScript 学习笔记(六):函数类型中我们学习了TS中的函数类型,本篇文章我们主要了解TS最常用也是最重要的一部分-泛型

如果你也和我一样在为大厂冲刺的话,欢迎添加我的微信lx3122178991,这里有一群小伙伴有着和你同样的目标,欢迎来一起讨论,一同进步。

泛型介绍

我们经常会在写TS类型的时候,碰到这样一个问题。函数返回值的类型与参数类型是相关的,有时我们不能一开始就定下类型。

比如:

TS 复制代码
function getFirst(arr) {
  return arr[0];
}

上面示例中,函数getFirst()总是返回参数数组的第一个成员。参数数组是什么类型,返回值就是什么类型。 这样的话,这个函数的类型声明只能写成下面这样。

TS 复制代码
function f(arr:any[]):any {
  return arr[0];
}

为了解决这个问题,TypeScript 就引入了"泛型"(generics)。泛型的特点就是带有"类型参数"(type parameter)。

TS 复制代码
function getFirst<T>(arr:T[]):T {
  return arr[0];
}

函数getFirst()的函数名后面尖括号的部分<T>,就是类型参数,参数要放在一对尖括号<>里面。

泛型在函数调用时,需要提供类型参数。 下面的例子中,调用函数getFirst()时,需要在函数名后面使用尖括号,给出类型参数T的值,本例是<number>

TS 复制代码
getFirst<number>([1, 2, 3])

泛型的类型参数的名字,可以随便取,但是必须为合法的标识符。 习惯上,类型参数的第一个字符往往采用大写字母。一般会使用T(type 的第一个字母)作为类型参数的名字。如果有多个类型参数,则使用 T 后面的 U、V 等字母命名,各个参数之间使用逗号(",")分隔。

例子。

TS 复制代码
function map<T, U>(
  arr:T[],
  f:(arg:T) => U
):U[] {
  return arr.map(f);
}

// 用法实例
map<string, number>(
  ['1', '2', '3'],
  (n) => parseInt(n)
); // 返回 [1, 2, 3]

上面示例中,将数组的实例方法map()改写成全局函数,它有两个类型参数TU含义是,原始数组的类型为T[],对该数组的每个成员执行一个处理函数f,将类型T转成类型U,那么就会得到一个类型为U[]的数组。

总之,泛型可以理解成一段类型逻辑,需要类型参数来表达。有了类型参数以后,可以在输入类型与输出类型之间,建立一一对应关系。

泛型的写法

TS泛型一般会在以下的场合中使用到:

  • 函数
  • 接口
  • 别名

函数的泛型写法

function关键字定义的泛型函数,类型参数放在尖括号中,写在函数名后面。

TS 复制代码
function id<T>(arg:T):T {
  return arg;
}

那么对于变量形式定义的函数,泛型有下面两种写法。

TS 复制代码
// 写法一
let myId:<T>(arg:T) => T = id;

// 写法二
let myId:{ <T>(arg:T): T } = id;

接口的泛型写法

interface 也可以采用泛型的写法。

TS 复制代码
interface Box<Type> {
  contents: Type;
}

let box:Box<string>;

上面示例中,使用泛型接口时,需要给出类型参数的值

类的泛型写法

泛型类的类型参数写在类名后面。

TS 复制代码
class Pair<K, V> {
  key: K;
  value: V;
}

继承泛型类的例子。

TS 复制代码
class A<T> {
  value: T;
}

class B extends A<any> {
}

上面示例中,类A有一个类型参数T,使用时必须给出T的类型,所以类B继承时要写成A<any>

类型别名的泛型写法

type定义的类型别名,也可以使用泛型。

TS 复制代码
type Nullable<T> = T | undefined | null;

上面示例中,Nullable<T>是一个泛型,只要传入一个类型,就可以得到这个类型与undefinednull的一个联合类型。

泛型的默认值

泛型可以设置默认值。使用时,如果没有给出泛型的值,就会使用默认值。

TS 复制代码
function getFirst<T = string>(
  arr:T[]
):T {
  return arr[0];
}

上面示例中,T = string表示类型参数的默认值是string。调用getFirst()时,如果不给出T的值,TS就认为T等于string

但是,TS会依靠实际参数进行类型推断从而得出T的值,从而覆盖掉默认值。

相关推荐
我要洋人死43 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風6 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#