泛型Generice

泛型基本了解

  1. 泛型指代的是宽泛的类型,‘型’指代的是类型,‘泛’宽泛的,不确定的,泛型还是通过严格类型,去约束程序,
  2. 确定类型
let a:string = '确定类型' 1.  这个变量必须要传递的是字符串类型的数据
  1. 泛型,也是控制类型的,使用方式与类型相同,只不过类型是动态指定的类型

  2. 泛型允许我们给类型传递参数,也就是动态的设置某一个函数或者是属性设置‘类型’

1. 复用函数

function uname<T>(name: T): T {
	return name
}

let str = uname<string>('泛型的基本使用')

console.log(str)
  1. ‘T’代表的是类型,并不是值,我们使用了 类型变量,它是一种特殊的变量,只用于表示类型而不是值。
  2. 泛型也是可以自动推断类型的,如果不给他传递明确的类型,他会根据传入的值,去推断,值是什么的类型。

泛型的继承

使用泛型约束函数

function user<T>(num:T) : T {
	return num.length
}

console.log(user<number>(5))  // 打印结果报错

为什么会出现类型‘T’上不存在length属性,原因是,‘T’类型他是我们动态传递的类型,并且‘num’没有明确的地方指出,它存在‘length’属性。也就是说,这个‘num’的类型可以是任意的类型,所以当使用函数者传递了‘number’类型,就会导致报错

  1. 解决方案(1)
1. 使用继承,继承其他类型,其他类型有这个属性,就不会报错了
function uname<T extends string>(num:T):number { 1.  返回值是number,是因为T继承了string类型
  return num.length 
}

console.log(uname<string>('lagou.com'));
  1. 解决多种类型的继承,解决方案
1. 使用联合类型,通过让T继承‘联合类型’
function uname<T extends any[] | string>( num:T ):number {
	return num.length 
}

console.log(uname<string>('lagou.com'));
console.log(uname<any[]>([1,2,3,4,5,6]));
  1. 如果一个函数的参数,一定是一个数组,那么他一定会有 length 属性,那么泛型这时候约束的不再是数组本身,而是数组中的元素,在传递类型的时候,传递什么类型,数组中的元素就是什么类型
function uname<T>(num:T[]): number {
  return num.length
}
console.log(uname<number>([1,2,3,4,5,6,7]));

2. 如果想要数组里面允许存放‘数值类型和字符串类型’,我们可以使用联合类型声明

function uname<T>(num:T[]): number {
  return num.length
}
console.log(uname<number | string>([1,2,3,4,5,6,7,'str']));
  1. ‘T’就是动态的类型,传递什么类型,他就是什么类型,如果在函数里面调用‘参数’里面的某一个属性,他不会成功,由于‘T’目前内部没有任何的‘类型约束’,他的类型来源于调用者的传递,所以起初会报错。在这种特殊的情况下使用‘继承’,继承其他类型,其他类型拥有这个属性,即可

类中使用泛型

class User<T> {
  data:T[] = []; 
  
  public push(...item: T[]) {
    return this.data.push(...item)
  }

  public shift():T {
    return this.data.shift()
  }
}

let user = new User<number>()

user.push(1,2,3,4,5,6,7)

user.shift()

构造函数中使用泛型

通过泛型,去约束构造函数接收或者是传递的数据,以确保程序的健壮性。

{

  class User<T> {
    private _u: T = null;
    public constructor(n: T) {
      this._u = n
    }
    public get(): T {
      return this._u
    }
  }
  interface StrUser {
    name: string,
    age: number
  }
  let user = new User<StrUser>({name:'小明',age: 18})

  console.log(user.get());
  
}

接口中使用泛型

‘泛型’的多类型定义,多类型定义可以通过在【< T , B >】逗号的方式,创建多个‘泛型’,供给多个属性进行使用

{

  interface User<B,C> {
    title: string;
    isLogin: B,
    comments: C
  }

  type comments =  {
    phone:number
    count: number
  }

  const str: User<boolean,comments> = {
    title: '当前用户',
    isLogin: true,
    comments: {
      phone: 666666,
      count: 666666
    }
  }
  console.log(str);
  

}
全部评论

相关推荐

10-30 23:23
已编辑
中山大学 Web前端
去B座二楼砸水泥地:这无论是个人素质还是专业素质都👇拉满了吧
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务