泛型

指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。

引入

下面创建一个函数, 实现功能: 根据指定的数量 count 和数据 value , 创建一个包含 countvalue 的数组 不用泛型的话,这个函数可能是下面这样:

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个参数valuecount,返回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[],函数createArrayvalue参数和返回类型都由用户自己决定。

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)泛型的更多相关文章

  1. TypeScript 素描 - 泛型、枚举

    /* 泛型,好处多多的功能.不过这里最基本的就不打算说了,仅准备说一些 和C#不同的地方 */ /* 泛型接口 GenericIdentityFn 定义了方法的描述等 identity方法则是它的实现 ...

  2. TypeScript Generics(泛型)

    软件工程的一个主要部分就是构建组件,构建的组件不仅需要具有明确的定义和统一的接口,同时也需要组件可复用.支持现有的数据类型和将来添加的数据类型的组件为大型软件系统的开发过程提供很好的灵活性. 在C#和 ...

  3. TypeScript入门-泛型

    泛型 要创建一个可重用的组件,其中的数据类型就必须要兼容很多的类型,那么如何兼容呢,TypeScript提供了一个很好的方法:泛型 Hello World 要兼容多种数据格式,可能会有人想到any,即 ...

  4. TypeScript 之 泛型

    https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/Generics.html 泛型:可以支持多种类型的数据 泛型函数的 ...

  5. React + TypeScript 实现泛型组件

    泛型类型 TypeScript 中,类型(interface, type)是可以声明成泛型的,这很常见. interface Props<T> { content: T; } 这表明 Pr ...

  6. typescript interface 泛型

    interface interface Obj { [index: string]: any; } class Person { name: string; } let obj: obj = { na ...

  7. TypeScript之泛型

    什么是泛型,有什么用? 泛型字面意思就是广泛的类型,怎么样才算广泛呢?当然是能变的最广泛嘛, 所谓泛型就是类型的变量写法,让你的变量的类型是动态可变的,应用场景如官方文档描述的例子: 一个函数,输入什 ...

  8. TypeScript入门六:TypeScript的泛型

    泛型函数 泛型类 一.泛型函数 在泛型函数之前,先简单的描述一下泛型,将变量定义成泛型可以在使用变量时来决定它的类型.什么意思呢?假如现在有一个函数,可能出现参数和返回值出现多种情况的现象,只有在调用 ...

  9. typescript - 6.泛型

    泛型类 class MinClas<T>{ public list:T[]=[]; add(value:T):void{ this.list.push(value); } min():T{ ...

  10. 转载:《TypeScript 中文入门教程》 9、泛型

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性. 组件不 ...

随机推荐

  1. Java基础之浅谈泛型

    简单的介绍了Java泛型类型的使用.上手容易,深入很难.

  2. python基础练习题(题目 使用lambda来创建匿名函数。)

    day34 --------------------------------------------------------------- 实例049:lambda 题目 使用lambda来创建匿名函 ...

  3. 全栈交叉编译X86完成过程经验分享

    1 CMAKE的交叉编译配置 主要是C和C++编译器的配置和SYSROOT的配置. set (CMAKE_SYSTEM_NAME "Linux") set (CMAKE_SYSTE ...

  4. zookeeper的linux安装

    wget下载(很慢):wget http://archive.apache.org/dist/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz 或者 ...

  5. 网络协议OSI模型-TCP/IP-三次握手

    OSI模型 在制定计算机网络标准方面,起着重大作用的两大国际组织是:国际电信联盟电信标准化部门,与国际 标准组织(ISO),虽然它们工作领域不同,但随着科学技术的发展,通信与信息处理之间的界限开始 变 ...

  6. [总结] 零散的 tricks

    对于类似构造方案的题目,先确定其中一些关键位置的方案,然后看是否能较为简单地推出其他位置的方案. 一个长度为 \(n\) 的序列,满足 \[a_1\le-a_4\le a_7\le-a_{10}\le ...

  7. 「BUAA OO Unit 2 HW8」第二单元总结

    「BUAA OO Unit 2 HW8」第二单元总结 目录 「BUAA OO Unit 2 HW8」第二单元总结 Part 0 前言 Part 1 第五次作业 1.1 作业要求 1.2 架构设计 1. ...

  8. 实战|Linux大文件切割

    一个执着于技术的公众号 日常工作中需要对日志文件进行分析,当日志文件过大时,Linux中使用vim.cat.grep.awk等这些工具对大文件日志进行分析将会成为梦魇,具体表现在: 执行速度缓慢,文件 ...

  9. 简单易懂的 Go 泛型使用和实现原理介绍

    原文:A gentle introduction to generics in Go by Dominik Braun 万俊峰Kevin:我看了觉得文章非常简单易懂,就征求了作者同意,翻译出来给大家分 ...

  10. springcloud + nacos实现共用基础服务(灰度版本)

    背景: 当我们使用微服务时,若想在本地联调就需要启动多个服务,为了避免本地启动过多服务,现将注册中心等基础服务共用.当我们在服务A开发时,都是注册到同一个nacos,这样本地和开发环境的服务A就会同时 ...