10_TypeScript中的泛型

一、泛型的定义

**泛型:**软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性,组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
在像 C# 和 Java 这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。这样用户就可以已自己的数据类型来使用组件。
通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持

二、泛型函数

// 只能返回string 类型的数据
function getData(value: string):string {
  return value

}
//同时返回 string 类型和number 类型,代码冗余
function getData1(value: string):string {
  return value
}
function getData2(value: number):number {
  return value
}
// 同时返回 string 类型和number 类型, any 可以解决这个问题,但是相当于放弃了类型检查.
function getData3(value: any):any {
  return value
}

需求: 传入什么就返回什么类型。 any 实现的时候传入和返回可以不一样的类型,此时我们可以使用泛型来解决。any 的性能比泛型差

function getData<T>(value:T):T {
  return value
}

// console.log(getData<number>('13')) // 错误写法
console.log(getData<number>(123)) // 正确写法
console.log(getData<string>('123')) // 正确写法

三、泛型类:比如有个最小堆算法,需要同时支持返回数字和字符串两种类型。通过类的泛型来实现

只能传入数字类型

class MinClass {
  list:number[] = [];
  add(num: number) {
    this.list.push(num)
  }
  min():number {
    let minNum = this.list[0]
    this.list.forEach(el=>{
      if(el<minNum) {
        minNum = el
      }
    })
    console.log(minNum)
    return minNum
  }
}
var m = new MinClass()
m.add(2)
m.add(28)
m.add(-2)
m.add(22)
m.add(92)
console.log(m.min())

类的泛型,传入和返回的一致

class MinClass<T> {
  list:T[] = [];
  add(num: T):void {
    this.list.push(num)
  }
  min():T {
    let minNum = this.list[0]
    this.list.forEach(el=>{
      if(el<minNum) {
        minNum = el
      }
    })
    console.log(minNum)
    return minNum
  }
}

var m = new MinClass<number>() // 实例化类,并且指定了类的 T 代表的类型是number
m.add(2)
m.add(28)
m.add(-2)
m.add(92)
console.log(m.min())

泛型的好处: 首先是有类型校验,其次是能够实现传入什么返回什么。

四、泛型接口

// 函数类型接口
interface ConfigFn{
  (value: string, value2:string):string
}
var setData:ConfigFn = function(val:string, val2:string):string {
  return val+val2
}
setData('name', 'lisi')

第一种定义泛型接口

interface ConfigFn{
 <T>(value: T):T
}
var setData:ConfigFn= function<T>(val:T):T {
  return val
}
setData<string>('name')
setData<number>(12334)

第二种定义泛型接口

interface ConfigFn<T>{
 (value: T):T
}
function setData<T>(val:T):T {
  return val
}
var mySetData:ConfigFn<string> = setData;

mySetData('name') // 正确写法
mySetData(12334) // 错误写法

五、泛型类 --扩展 把类作为参数类型的泛型类

泛型类:泛型可以帮助我们避免重复的代码以及对不特定数据类型的支持(类型校验),下面我们看看把类当作参数的泛型类
1、定义个类
2、把类作为参数来约束数据传入的类型

1、实现:定义一个 User 的类,这个类的作用就是映射数据库字段,然后定义一个 MysqlDb 的类,这个类用于操作数据库,然后把 User 类作为参数传入到 MysqlDb 中

var user = new User({
	username: "zhangsan",
	password: "a123456"
})
var Db = new MysqlDb()
Db.add(user)
// 把类作为参数来约束
class User{
  username: string|undefined;
  passwrod: string|undefined
}

class MysqlDb{
  list:User[] = []
  add(user: User):boolean{
    this.list.push(user)
    return true
  }

}

let u = new User()
u.username = 'lis'
u.passwrod = '123456'

let Db = new MysqlDb()
Db.add(u)

动态的校验 MysqlDb 类

// 操作数据库的泛型类
class MysqlDb<T>{
  list:T[] = []
  add(user: T):boolean{
    this.list.push(user)
    return true
  }
}
// 1、定义一个 User 类 和数据库进行映射
class User{
  username: string|undefined;
  passwrod: string|undefined
}


let u = new User()
u.username = 'lisisi'
u.passwrod = '123456'

//let Db = new MysqlDb()// 这种方法是有问题的,能够传入任意的类型,没有做校验
let Db = new MysqlDb<User>() // 这种方法可以正常校验
Db.add(u)

class ArticelCate{
  title: string|undefined;
  desc: string|undefined;
  status: number | undefined
  constructor(params:{
    title: string|undefined,
    desc: string|undefined,
    status: number | undefined
  }) {
    this.title = params.title
    this.desc = params.desc
    this.status = params.status
  }
}
let article = new ArticelCate({
  title: '今日新闻', 
  desc: "1233",
  status: 1
})
let Db2 = new MysqlDb<ArticelCate>()
Db.add(article)
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值