描述

  • 给函数添加类型变量T(使用尖括号<>包裹),它可以捕获用户传入参数的类型,并且使用T作为返回值类型。
  • 它可以保证传递进函数的参数类型与返回值类型完全一致。
  • 泛型函数适用于多种类型,相较于使用any类型,它不会丢失类型信息。

固定泛型参数

 const getArr = <T>(value: T, times: number = 5): T[] => {
   return new Array(times).fill(value)
 }

 let len = getArr<string>('123', 3).map((item) => item.length) 
 let lens = getArr<number>(123, 3).map((item) => Number(item.toFixed()))
console.log(len)
console.log(lens)

省略泛型参数

  • 省略泛型的类型参数,编译器可以根据传递的参数自动推断T的类型。
/*
去掉上面getArr后尖括号就可以了,编辑器会自动根据参数的类型来推断T的类型
*/
 let getArrays: <S, N>(value: S, times: N) => S[] //2个泛型参数
 getArrays = (value, times) => {
   return new Array(times).fill(value)
 }
 console.log(getArrays<string, number>('1', 2))

用泛型约束函数

 let getArrays: <S>(value: S, times: number) => S[] 
 getArrays = (value, times) => {
   return new Array(times).fill(value)
 }
 console.log(getArrays<string>('1', 2))

类型别名与接口方式

interface GetArray {
  <S>(value: S, times: number): S[]
}
// type GetArray = <S>(value: S, times: number) => S[]
let getArrays: GetArray = (value, times) => {
  return new Array(times).fill(value)
}
console.log(getArrays('1', 2))

约束泛型

  • 当这种情况下:当想约束该泛型,必须具有某一属性时
// 泛型约束
 interface ArrayLength { // 定义一个接口,必须含有length类型为number
   length: number
 }
 const getArr = <T extends ArrayLength>(value: T, times): T[] => {
   return new Array(times).fill(value)
 }
 console.log(getArr('1', 2))
 console.log(getArr({ a: 1, length: 2 }, 2))// 对象自定义了一个length,不会报错
 console.log(getArr(1,2)//这里会报错,数值没有length属性
  • 获取一个对象中没有的属性时,返回是undefined,但是这时定义的泛型并没有进行参数,所以编辑器内并不会报错
let getArr = <T, K extends keyof T>(obj: T, key: K) => {
//K extends keyof T 理解成 K继承T中所有的属性
  return obj[key]
}
let obje = {
  a: 1,
  b: 2
}
console.log(getArr(obje, 'a'))
console.log(getArr(obje, 'c')) // undefined 这里编辑器内报错了

爬。