泛型

1.什么是泛型?

  • 在编写代码的时候我们既要考虑代码的健壮性,又要考虑代码的灵活性和可重用性
  • 通过TS的静态检测能让我们编写的代码变得更加健壮,但是在变得健壮的同时却丢失了灵活性和可重用性

所以为了解决这个问题TS推出了泛型的概念

  • 通过泛型不仅可以让我们的代码变得更加健壮,还能让我们的代码在变得健壮的同时保持灵活性和可重用性
  1. // 定义一个创建数组的方法,可以创建出指定长度的数组,并且可以用任意指定的内容填充这个数组
  2. let getArray = (value:any, items:number = 5):any[]=>{
  3. return new Array(items).fill(value);
  4. }
  5. let arr1 = getArray('abc',3) // arr1 = ['abc','abc','abc']
  6. let arr2 = getArray(666,4) // arr1 = [666,666,666,666]
  7. // 当前代码的问题:
  8. //1.编写代码没有提示,因为TS的静态检测不知道具体是什么类型
  9. //例:下面代码没有.length提示
  10. let res1 = arr1.map(item=>item.length) //['abc','abc','abc'] => [3,3,3]
  11. //2.哪怕我们代码写错了也不会报错,因为TS的静态检测不知道具体是什么类型
  12. // 例:
  13. let res2 = arr2.map(item=>item.length) //[666,666,666,666] => [undefined,undefined,undefined,undefined]
  • 需求:要有代码提示,如果写错了要在编译的时候出错
  1. // 定义一个创建数组的方法,可以创建出指定长度的数组,并且可以用任意指定的内容填充这个数组
  2. let getArray = <T>(value:T, items:number = 5):T[]=>{
  3. return new Array(items).fill(value);
  4. }
  5. let arr1 = getArray<string>('abc',3) // arr1 = ['abc','abc','abc']
  6. let arr2 = getArray<number>(666,4) // arr1 = [666,666,666,666]
  7. //例:此时代码有.length提示
  8. let res1 = arr1.map(item=>item.length) //['abc','abc','abc'] => [3,3,3]
  9. // 例:报错
  10. let res2 = arr2.map(item=>item.length) //报错
  11. //注意点:泛型具体的类型可以不指定,如果没有指定,那么就会根据我们传递的泛型参数自动推导出来
  12. let arr3 = getArray('abc',3) // arr1 = ['abc','abc','abc']

泛型约束

1.什么是泛型约束?

  • 默认情况下我们可以指定泛型为任意类型
  • 但是有些情况下我们需要指定的类型满足某些条件后才能指定
  • 那么这个时候我们就可以使用泛型约束
  1. // 需求:要求指定的泛型类型必须由length属性才可以
  2. interface LengthInterface{
  3. length:number
  4. }
  5. let getArray = <T extends LengthInterface>(value:T, items:number = 5):T[]=>{
  6. return new Array(items).fill(value);
  7. }
  8. let arr1 = getArray<string>('abc',3) // arr1 = ['abc','abc','abc'] string有length属性,不报错
  9. let arr2 = getArray<number>(666,4) // number没有length属性,报错

在泛型约束使用类型参数

  • 一个泛型被另一个泛型约束,就叫做泛型约束中使用类型参数
  1. // 需求:定义一个函数用于根据指定的key获取对象的value
  2. interface KeyInteface {
  3. [key:string]:any
  4. }
  5. let getProps = (obj:KetInterface, key:string):any=>{
  6. return obj[key]
  7. }
  8. let obj = {
  9. a:'a',
  10. b:'b'
  11. }
  12. // 代码不够健壮,明明obj中没有c这个key但是却没有报错
  13. let res = getProps(obj,'c')
  1. // 需求:定义一个函数用于根据指定的key获取对象的value
  2. let getProps = <T, K extends keyof T>(obj:T, key:K):any=>{
  3. return obj[key]
  4. }
  5. let obj = {
  6. a:'a',
  7. b:'b'
  8. }
  9. let res = getProps(obj,'c') // 报错