乐趣区

关于前端:一文说清楚TypeScript-的泛型

●泛型 (generic) : 先来看一下百度给出的中文解释

●这一章咱们就来学习一下什么是 TS 内的泛型

泛型
●废话不多说, 间接上例子

初识泛型
●一个函数, 须要参数是 number 数据类型, 返回值也是 number 数据类型

function fn(arg: number): number {// 代码忽略不计}

●又一个函数, 须要参数是 string 类型, 返回值也是 string 数据类型

function fn(arg: string): string {// 代码忽略不计}

●咱们发现, 咱们给函数的参数和返回值都进行了限度
○假如, 如果两段代码的业务逻辑一样
○咱们能够不可把两个函数写成一个
○需要 : 我传递的是 数字, 返回值就是数字, 传递的是 字符串, 返回值就是 字符串
● 思考过后, 咱们想到能够用 或 (|)

function fn(arg: number | string): number | string {// 代码忽略不计}

○看起来不错
○然而不能齐全满足咱们的需要
■参数 number 返回值 number
■参数 number 返回值 string
■参数 string 返回值 number
■参数 string 返回值 string
○以上四种状况都是能够的
○和咱们预期的需要不一样
●我也能够写成 any 类型不就好了

function fn(arg: any): any {// 代码忽略不计}

○这样一来, 如同对参数和返回值的限度又都没有了
○那么 TS 的意义如同不大了
●难道说用了 TS 当前, 咱们的代码反而不灵便了吗 ?
●来看上面一段代码

function fn<T>(arg: T): T {// 代码忽略不计}

○这个玩意看起来怪怪的, 感觉意识但又不齐全意识
○这里函数名前面的 “<T>” 示意给该函数定义了一个泛型, 就是预设了一个类型限度
○未来你调用这个函数的时候, 来传递一个类型对函数进行束缚

// 用 string 去填充预设
// 以后函数的参数必须是 string, 返回值也必须是 string
fn<string>('hello')

// 用 number 去填充预设
// 以后函数的参数必须是 number, 返回值也必须是 number
fn<number>(100)

○在来思考咱们一开始的需要, 其实次要就是取决于调用的时候
●泛型, 其实就是在定义阶段不预先指定具体类型, 只是留下一个空位或者预设地位, 当你应用的时候在决定应用什么具体的数据类型填充

泛型用法
1. 函数泛型
○就是利用泛型限定函数的参数和返回值

function test <T>(arg: T): T{
  // ... 此处省略代码 10000 行
  return arg
}
test<number>(111) // 返回值是 number 类型

○也能够设置多个泛型标识符

function test <T, U>(arg1: T, arg2: U): [U, T]{
  // ... 此处省略代码 10000 行
  return [arg2, arg1]
} 
test<number, string>(100, 'hello world')

○泛型标识符能够设置一个, 也能够设置多个, 用哪个字母无所谓

2. 接口泛型
○在定义接口的时候, 也能够应用泛型

interface User<T> {gender: T}

const p1: User<string> = {gender: '男'}

const p2: User<boolean> = {gender: true}

○这样看起来, 泛型是不是十分不便呢
○同样, 也能够设置一个, 也能够设置多个

// 制作一个办法的接口泛型
interface Search {<T, Y>(name: T,age: Y): T
}

let fn:Search = function <T, Y>(name: T, id: Y): T {
  // ... 此处省略代码 10000 行
  return name;
}

3. 类泛型
○在定义类的时候, 咱们也能够退出一些泛型限度一些内容

class Animal<T> {
  name: T
  constructor(name: T){this.name = name}
  action<T>(say: T) {console.log(say)
  }
 }
 let cat = new Animal<string>('千锋大前端')
 cat.action<string>('Hello, 欢送来到千锋大前端')

断言
●断言是一个十分有意思的小玩意, 有的时候能够在我无助的时候给我带来一丝心愿
●我始终感觉断言就是 “ 奥特曼 ”

●看一个例子

// 获取了一个页面上的 div 元素
const ele = document.querySelector('div')

// 制作一个简略的性能函数, 要求参数承受一个 DIV 元素
function util(ele: HTMLDivElement): void {}

// 调用函数传入参数
util(ele)

○在失常不过的一段代码了, 这个有啥的
○写完咱们才发现

●为什么 ? 为什么 ?

●会不会是因为我定义 ele 变量的时候, 没有限度类型呢

●这回上面好了, 下面又出问题了
●解释一下吧
○其实是因为, 咱们获取元素这个操作, 是有可能获取不到的
○当咱们获取不到的时候就是 null
○就不是 HTMLDivElement 这个类型了
○所以在哪个中央限度好当前, 都会呈现问题的
●怎么办呢, 这个时候, 就能够应用断言了
○断言其实就是我主观给他强制定义一个类型, 这样就不会呈现问题了

const ele = document.querySelector('div') as HTMLDivElement

function util(ele: HTMLDivElement): void {}

util(ele)

○这里我就强制把 ele 元素判定为 HTMLDivElement 类型, 那么就不会呈现问题了
●其实在很多时候, 咱们不确定, 或者拿不准的时候, 咱们都能够应用断言来解决问题
○先不让他报错, O(∩_∩)O~
○剩下的前面再说

退出移动版