TypeScript 的泛型
这一章我们就来学习一下什么是 TS 内的泛型
泛型
● 废话不多说, 直接上例子
初识泛型
● 一个函数, 需要参数是 number 数据类型, 返回值也是 number 数据类型
function fn(arg: number): number {
// 代码忽略不计
}
● 又一个函数, 需要参数是 string 类型, 返回值也是 string 数据类型
function fn(arg: string): string {
// 代码忽略不计
}
● 我们发现, 我们给函数的参数和返回值都进行了限制
○ 假设, 如果两段代码的业务逻辑一样
○ 我们可以不可把两个函数写成一个
○ 需求 : 我传递的是 数字, 返回值就是数字, 传递的是 字符串, 返回值就是 字符串
● 思考过后, 我们想到可以用 或( | )
function fn(arg: number | string): number | string {
// 代码忽略不计
}
○ 看起来不错
○ 但是不能完全满足我们的需求
■ 参数 number 返回值 number
■ 参数 number 返回值 string
■ 参数 string 返回值 number
■ 参数 string 返回值 string
○ 以上四种情况都是可以的
○ 和我们预期的需求不一样
● 我也可以写成 any 类型不就好了
function fn(arg: any): any {
// 代码忽略不计
}
○ 这样一来, 好像对参数和返回值的限制又都没有了
○ 那么 TS 的意义好像不大了
● 难道说用了 TS 以后, 我们的代码反而不灵活了吗 ?
● 来看下面一段代码
function fn(arg: T): T {
// 代码忽略不计
}
○ 这个玩意看起来怪怪的, 感觉认识但又不完全认识
○ 这里函数名后面的 "" 表示给该函数定义了一个泛型, 就是预设了一个类型限制
○ 将来你调用这个函数的时候, 来传递一个类型对函数进行约束
// 用 string 去填充预设
// 当前函数的参数必须是 string, 返回值也必须是 string
fn('hello')
// 用 number 去填充预设
// 当前函数的参数必须是 number, 返回值也必须是 number
fn(100)
○ 在来思考我们一开始的需求, 其实主要就是取决于调用的时候
● 泛型, 其实就是在定义阶段不预先指定具体类型, 只是留下一个空位或者预设位置, 当你使用的时候在决定使用什么具体的数据类型填充
泛型用法
1. 函数泛型
○ 就是利用泛型限定函数的参数和返回值
function test(arg: T): T{
// ... 此处省略代码 10000 行
return arg
}
test(111) // 返回值是 number 类型
○ 也可以设置多个泛型标识符
function test <t, u="">(arg1: T, arg2: U): [U, T]{
// ... 此处省略代码 10000 行
return [ arg2, arg1 ]
}
test<number, string="">(100, 'hello world')
○ 泛型标识符可以设置一个, 也可以设置多个, 用哪个字母无所谓
2. 接口泛型
○ 在定义接口的时候, 也可以使用泛型
interface User{
gender: T
}
const p1: User= {
gender: '男'
}
const p2: User= {
gender: true
}
○ 这样看起来, 泛型是不是非常方便呢
○ 同样, 也可以设置一个, 也可以设置多个
// 制作一个方法的接口泛型
interface Search {
<t, y="">(name: T,age: Y): T
}
let fn:Search = function <t, y="">(name: T, id: Y): T {
// ... 此处省略代码 10000 行
return name;
}
3. 类泛型
○ 在定义类的时候, 我们也可以加入一些泛型限制一些内容
class Animal{
name: T
constructor(name: T){
this.name = name
}
action(say: T) {
console.log(say)
}
}
let cat = new Animal('千锋大前端')
cat.action('Hello, 欢迎来到千锋大前端')
断言
● 断言是一个非常有意思的小玩意, 有的时候可以在我无助的时候给我带来一丝希望
● 我一直觉得断言就是 "奥特曼"
● 看一个例子
// 获取了一个页面上的 div 元素
const ele = document.querySelector('div')
// 制作一个简单的功能函数, 要求参数接受一个 DIV 元素
function util(ele: HTMLDivElement): void {}
// 调用函数传入参数
util(ele)
○ 在正常不过的一段代码了, 这个有啥的
○ 写完我们才发现
会不会是因为我定义 ele 变量的时候, 没有限制类型呢
这回下面好了, 上面又出问题了
● 解释一下吧
○ 其实是因为, 我们获取元素这个操作, 是有可能获取不到的
○ 当我们获取不到的时候就是 null
○ 就不是 HTMLDivElement 这个类型了
○ 所以在哪个地方限制好以后, 都会出现问题的
● 怎么办呢, 这个时候, 就可以使用断言了
○ 断言其实就是我主观给他强制定义一个类型, 这样就不会出现问题了
const ele = document.querySelector('div') as HTMLDivElement
function util(ele: HTMLDivElement): void {}
util(ele)
○ 这里我就强制把 ele 元素断定为 HTMLDivElement 类型, 那么就不会出现问题了
● 其实在很多时候, 我们不确定, 或者拿不准的时候, 我们都可以使用断言来解决问题
○ 先不让他报错, O(∩_∩)O~
○ 剩下的后面再说
相关推荐HOT
更多>>如何添加Java环境变量?
要添加Java环境变量,可以按照以下步骤:并安装Java开发工具包(JDK)、找到Java安装路径、设置JAVA_HOME环境变量、添加Java可执行文件路径到PATH...详情>>
2023-05-04 11:00:56从零开始学Java之String字符串的编码
对很多小白来说,可能不明白什么是字符编码,也不知道为什么要有字符编码,所以先来给大家简要地介绍一下字符编码。详情>>
2023-05-04 10:21:02新手速来!几步带你掌握MyBatis Plus
Mybatis-Plus(简称MP)是一款Mybatis的增强工具,它是在Mybatis的基础上实现的简化开发工具。Mybatis-Plus给我们提供了开箱即用的CRUD操作、自动...详情>>
2023-04-28 10:57:09学习java需要什么基础?基础知识有哪些?
网络编程:了解基本的网络编程概念和协议,熟悉 Java 网络编程 API。建议在学习 Java 之前,先学习一些基础的编程语言,如 C 或 Python 等,这...详情>>
2023-04-28 10:41:14