首页 > 其他 > 详细

TypeScript - 泛型

时间:2019-12-01 13:41:14      阅读:62      评论:0      收藏:0      [点我收藏+]

什么是泛型

官方是这样介绍的:

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

从上面的信息概括为泛型是支持多种类型的变量,根据用户需求灵活的变动,达到复用组件的效果。
在实际开发中,有一个函数是同样的逻辑,只是因为类型的不同,就要再写一个函数,这样并没有达到代码复用的原则。正好泛型就可以用来解决这种问题。

例子

现在有一个处理数组的函数,这里只是简单的返回,当做进行处理

function formatArr(arr:Array<string>):Array<string>{
  return arr.map(item=>item)
}

如果这时候有其他类型的数组需要同样的操作,而 formatArr 只接受字符串数组,我们有什么方法来解决呢?

1. any

函数接受一个任意类型的数组,这确实能够解决问题,但是也失去了类型检查的意义

function formatArr(arr:Array<any>):Array<any>{
  return arr.map(item=>item)
}

2.重新定义函数

重新再写一个同样逻辑的函数,这看起来就不妥。如果还要接受更多的类型,而函数内部的逻辑复杂,这样重新定义多个同样逻辑的函数,会显得代码的冗余

function formatArr2(arr:Array<number>):Array<number>{
  return arr.map(item=>item)
}

3.泛型

面对这种需要接受多类型的函数,泛型才是正解。因为泛型的灵活性,我们不必在函数定义时就定义类型,而是执行时由使用者规定类型,达到代码复用的原则。

function formatArr<T>(arr:Array<T>):Array<T>{
  return arr.map(item=>item)
}

formatArr<string>(['1', '2', '3'])
formatArr<number>([1, 2, 3])

定义函数 formatArr 时,在函数名后定义一个类型变量 <T>,同时参数数组项也接受 T 类型的值。
由于 <T> 是一个变量,在使用函数时,使用者传入的类型即为 <T> 的类型。

尖括号内的变量名并不是固定的,可以自定义,一般都是大写

泛型类

泛型类实例化传入的泛型类型,可以在整个作用域中使用该泛型类型,但要注意的是类的静态属性无法使用泛型类型

class Handsome<T>{
  //static myname:T = 'Jack'  静态成员不能引用类类型参数
  girlfriend: Array<T>
  
  constructor(){
    this.girlfriend = []
  }

  addGirlfriend(name:T){
    this.girlfriend.push(name)
  }

  getAllGirlfriend():Array<T>{
    return this.girlfriend
  }
}
let handsome = new Handsome<string>()
handsome.addGirlfriend('Julia')
handsome.addGirlfriend('Vivian')
//handsome.addGirlfriend({name:'Ellie'})  类型“{ name: string; }”的参数不能赋给类型“string”的参数
handsome.getAllGirlfriend() // ['Julia', 'Vivian']

泛型约束

使用泛型约束来对 formatArr 做一些改造,改造后的函数功能为对传入的参数进行切片,返回除第一项的数据。

interface Slice{
  slice:Function;
}
function formatArr<T extends Slice>(arg:T):T{
  return arg.slice(1)
}
formatArr([1,2,3])
formatArr('hello')

但并不是每个类型都有 slice 方法,这时候就需要对泛型进行约束,规定只有slice 方法的参数才可以传入。
为此,定义一个含有 slice 方法的接口,使用这个接口和 extends 关键词实现约束。
这里可能你会想到接口继承,因为接口继承也使用了extends 关键词,但在泛型约束里并不是表示继承关系。

写在最后

泛型在typescript中是很重要的一点知识,理解并应用泛型,可以使我们的代码更加灵活。所以在编程时要多想想是否能够使用泛型来优化,让代码的复用性最大化。

TypeScript - 泛型

原文:https://www.cnblogs.com/chanwahfung/p/11965469.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!