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的值,从而覆盖掉默认值。

相关推荐
diemeng111911 分钟前
2024系统编程语言风云变幻:Rust持续领跑,Zig与Ada异军突起
开发语言·前端·后端·rust
烂蜻蜓13 分钟前
Uniapp 中布局魔法:display 属性
前端·javascript·css·vue.js·uni-app·html
java1234_小锋43 分钟前
一周学会Flask3 Python Web开发-redirect重定向
前端·python·flask·flask3
琑951 小时前
nextjs项目搭建——头部导航
开发语言·前端·javascript
light多学一点1 小时前
视频的分片上传
前端
Gazer_S2 小时前
【Windows系统node_modules删除失败(EPERM)问题解析与应对方案】
前端·javascript·windows
bigyoung2 小时前
基于 React 的列表实现方案,包含创建和编辑状态,使用 Modal 弹框和表单的最佳实践
前端
乌木前端2 小时前
包管理工具lock文件的作用
前端·javascript
司玄2 小时前
3dtiles平移旋转原理及可视化工具实现
前端
m0_748236582 小时前
本地部署轻量级web开发框架Flask并实现无公网ip远程访问开发界面
前端·tcp/ip·flask