泛型

llz大约 1 分钟

泛型函数

定义泛型函数,此函数有个类型变量 TT可以帮助我们捕获用户传入的类型

function getType<T>(type: T) {
  return type
}

调用泛型函数

//type 是number类型
getType<number>(1)

//不用 <> 时,type 就是字面量类型 123
getType("123")

泛型约束

如果我们想在函数里面获取 typelength 属性,但是编译器并不能确定type 上一定有 length 属性,所以编译器会报错:

  //Property  length  does not exist on type  T
  type.length

我们可以使用 typeof 关键字进行类型收缩

function getType<T>(type: T) {
  if (typeof type === "string") {
    type.substring(1)
  } else if (typeof type === "number") {
    type.toFixed(0)
  }

  return type
}

我们还可以定义一个接口,创建一个包含 length 属性的接口,使用 extends 关键字来实现约束。如果传入的参数没有 length 属性,(如数字100),编译器则会报错。

interface ILength{
  length:number
}

function getLength<T extends ILength>(type:T){
  console.log(type.length)
}

getLength('abc')

getLength([1,3])

//Error: Argument of type  number  is not assignable to parameter of type  ILength 
getLength(100)

泛型中使用 keyof

我们需要在下面这个泛型函数中用属性名从对象中获取这个属性值,如果直接使用 **obj[key]**的话会报错,因为编译器并不能确定这个对象上面一定会有key这个属性。

function getKey<O,K>(obj:O,key:K){
  //Error: Type  K  cannot be used to index type  O
  console.log(obj[key])
}

我们可以使用 keyof 关键字对 K 进行约束

//keyof O 可以理解为 O 的所有属性
function getKey<O,K extends keyof O>(obj:O,key:K){
  return obj[key]
}

const user={
  name:'rice',
  age:18
}

getKey(user,'name') //rice

//Error: Argument of type  "gender"  is not assignable to parameter of type  "name" | "age" 
getKey(user,'gender')

泛型接口

interface IUser<T>{
  id:T,
  name:string
}

const userInfo:IUser<number>={
  id:1,
  name:'rice'
}
上次编辑于: