TypeScript(7)泛型
泛型
指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。
引入
下面创建一个函数, 实现功能: 根据指定的数量 count 和数据 value , 创建一个包含 count 个 value 的数组 不用泛型的话,这个函数可能是下面这样:
function createArray(value: any, count: number): any[] {
const arr: any[] = []
for (let index=0; index < count; index++) {
arr.push(value)
}
return arr
}
const arr1 = createArray('a', 3)
const arr2 = createArray(1, 3)
console.log(arr1)
console.log(arr2)
console.log(arr1[0].toFixed(), arr2[0].split(''))
我们创建了一个函数createArray,传入2个参数value和count,返回any类型的数组,然后定义了一个any类型的空数组arr。接下来我们查看结果

在编译阶段我们没有报错是因为,我们把value设置为了any类型,但是当编译完成后运行时,arr1是字符串,字符串是没有toFixed方法的,所以会报错,那么我们希望在编译阶段就报错,就可以使用泛型
使用泛型
// 使用函数泛型
function createArray<T>(value: T, count: number): T[] {
const arr: Array<T> = []
for (let index=0; index < count; index++) {
arr.push(value)
}
return arr
}
const arr1 = createArray<number>(11, 3)
console.log(arr1[0].toFixed())
const arr2 = createArray<string>('AA', 3)
console.log(arr2[0].split(''))
console.log('---------')
console.log(arr2[0].toFixed()) // 报错,因为字符串没有toFixed方法
console.log(arr1[0].split('')) // 报错,因为number没有split方法
泛型的意思就是类型由用户自己决定,比如function createArray<T>(value: T, count: number): T[],函数createArray和value参数和返回类型都由用户自己决定。
const arr1 = createArray<number>(11, 3)这句代码是没问题,因为规定了number类型,传入的也是number
当我们将代码修改成如下代码:

我们发现报错了,因为规定了number类型,传入的却是字符串11,

当我们输入如下代码,也会报错

报错原因如下

所以如果我们使用了泛型,就会避免类型输入错误或者用错方法
多个泛型参数的函数
一个函数可以定义多个泛型参数
function swap <K, V> (a: K, b: V): [K, V] {
return [a, b]
}
const result = swap<string, number>('abc', 123)
console.log(result[0].length, result[1].toFixed())
泛型接口
interface IbaseCRUD <T> {
// 定义泛型数组data
data: T[]
add: (t: T) => void
getById: (id: number) => T
}
class User {
id?: number;
name: string;
age: number;
constructor(name, age) {
this.name = name;
this.age = age;
}
}
class UserCRUD implements IbaseCRUD<User> {
data: User[] = []
add(user: User): void {
user = {...user, id: Date.now()}
this.data.push(user)
console.log('保存user', user.id)
}
getById(id: number): User {
return this.data.find(item => item.id === id)
}
}
const userCRUD = new UserCRUD()
userCRUD.add(new User('tom', 12))
userCRUD.add(new User('tom2', 13))
console.log(userCRUD.data)
泛型类
泛型类看上去与泛型接口差不多。 泛型类使用( <>)括起泛型类型,跟在类名后面。
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
GenericNumber类的使用是十分直观的,并且你可能已经注意到了,没有什么去限制它只能使用number类型。 也可以使用字符串或其它更复杂的类型。
let stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "";
stringNumeric.add = function(x, y) { return x + y; };
console.log(stringNumeric.add(stringNumeric.zeroValue, "test"));
与接口一样,直接把泛型类型放在类后面,可以帮助我们确认类的所有属性都在使用相同的类型。
泛型约束
如果我们直接对一个泛型参数取 length 属性, 会报错, 因为这个泛型根本就不知道它有这个属性
// 没有泛型约束
function fn <T>(x: T): void {
console.log(x.length) // 报错,因为目前不知道x是什么类型
}
我们可以使用泛型约束来实现
interface Lengthwise {
length: number;
}
// 指定泛型约束
function fn2 <T extends Lengthwise>(x: T): void {
console.log(x.length)
}
我们需要传入符合约束类型的值,必须包含必须 length 属性:
fn2('abc')
// fn2(123) // error number没有length属性
TypeScript(7)泛型的更多相关文章
- TypeScript 素描 - 泛型、枚举
/* 泛型,好处多多的功能.不过这里最基本的就不打算说了,仅准备说一些 和C#不同的地方 */ /* 泛型接口 GenericIdentityFn 定义了方法的描述等 identity方法则是它的实现 ...
- TypeScript Generics(泛型)
软件工程的一个主要部分就是构建组件,构建的组件不仅需要具有明确的定义和统一的接口,同时也需要组件可复用.支持现有的数据类型和将来添加的数据类型的组件为大型软件系统的开发过程提供很好的灵活性. 在C#和 ...
- TypeScript入门-泛型
泛型 要创建一个可重用的组件,其中的数据类型就必须要兼容很多的类型,那么如何兼容呢,TypeScript提供了一个很好的方法:泛型 Hello World 要兼容多种数据格式,可能会有人想到any,即 ...
- TypeScript 之 泛型
https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/Generics.html 泛型:可以支持多种类型的数据 泛型函数的 ...
- React + TypeScript 实现泛型组件
泛型类型 TypeScript 中,类型(interface, type)是可以声明成泛型的,这很常见. interface Props<T> { content: T; } 这表明 Pr ...
- typescript interface 泛型
interface interface Obj { [index: string]: any; } class Person { name: string; } let obj: obj = { na ...
- TypeScript之泛型
什么是泛型,有什么用? 泛型字面意思就是广泛的类型,怎么样才算广泛呢?当然是能变的最广泛嘛, 所谓泛型就是类型的变量写法,让你的变量的类型是动态可变的,应用场景如官方文档描述的例子: 一个函数,输入什 ...
- TypeScript入门六:TypeScript的泛型
泛型函数 泛型类 一.泛型函数 在泛型函数之前,先简单的描述一下泛型,将变量定义成泛型可以在使用变量时来决定它的类型.什么意思呢?假如现在有一个函数,可能出现参数和返回值出现多种情况的现象,只有在调用 ...
- typescript - 6.泛型
泛型类 class MinClas<T>{ public list:T[]=[]; add(value:T):void{ this.list.push(value); } min():T{ ...
- 转载:《TypeScript 中文入门教程》 9、泛型
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性. 组件不 ...
随机推荐
- 状态机引擎在vivo营销自动化中的深度实践 | 引擎篇02
本文是<vivo营销自动化技术解密>的第3篇文章,分析了营销自动化业务背景和状态机引入原因.状态机的三种基本实现方式,同时介绍了几种业界流行的开源状态机框架实现和特点,以及在项目开发过程中 ...
- HTML5有哪些新特性
(一) 语义标签 <header>表示页面中一个内容区块或整个页面的标题. <section>页面中的一个内容区块,如章节.页眉.页脚或页面的其他地方,可以和h1.h2--元 ...
- 1903021116—吉琛—Java第六周作业—类的定义
项目 内容 课程班级博客链接 19信计班 这个作业要求链接 第六周作业链接 java面向对象的概念和定义 博客名称 学号-姓名-Java第六周作业-题目自拟 要求 每道题要有题目,代码(使用插入代码, ...
- 用 DOM 获取页面的元素方法集合
document.getElementById('id名') // 获取页面设置指定 id 的元素 document.getElementsByTagName('标签名') ...
- git-config配置多用户环境以及 includeIf用法
git-config配置多用户环境以及 includeIf用法 git-config配置多用户环境以及 includeIf用法 背景 介绍 配置 栗子 背景 开发人员经常遇到这样的问题,公司仓库和个人 ...
- FreeRTOS --(0)简介
转载自https://blog.csdn.net/zhoutaopower/article/details/106541595 FreeRTOS 是一个嵌入式实时操作系统,具有相对(相对 Linux. ...
- MVC 的dao层、service层和controller层
1.dao层 dao层主要做数据持久层的工作, 负责与数据库进行联络的一些任务都封装在此 ,dao层的设计 首先 是设计dao层的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可以再模 ...
- [题解][P5206][WC2019] 数树 (op = 1)
简要题意 给定 \(n, y\). 一张图有 \(|V| = n\) 个点,现在给出两棵树 \(T_1=G(V, E_1)\) 和 \(T_2=G(V, E_2)\). 定义这两棵树的权值 \(F(E ...
- [题解] 树(tree)
题目大意 给定一颗 \(N\) 个点的有根树,其中 \(1\) 是树根,除了 \(1\) 以外的其他点 \(u\) 有唯一的父亲 \(Father_u\).同时,给定 \(M\) 条路径,第 \( ...
- ajax、axios、fetch
XMLHttpRequest: XHR中文解释为: 可扩展超文本传输请求:XML可扩展标记语言,Http超文本传输协议,Request请求: XHR对象用于与服务器交换数据,所有现代游览器都支持XHR ...