美文网首页javascriptTypeScript
TypeScript(六)泛型

TypeScript(六)泛型

作者: 一蓑烟雨任平生_cui | 来源:发表于2019-11-12 12:32 被阅读0次

泛型是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。一般用于解决类、方法、接口的复用性,以及对不特定数据类型的支持(类型校验)。

创建一个函数,要求函数的返回值就是函数的参数,参数类型是任意的。可以通过如下方式实现:

function echo(val: any): any {
  return val
}

以上使用any类型有几个不足之处:首先any类型ts会放弃类型检查,失去使用ts的初衷及优势;其次,既然返回值是any类型,并不能准确的定义返回值的类型。此时泛型就派上用场了。

泛型函数

实现一个函数,函数接收两个参数,返回值是参数1为参数,参数2为元素组成的数组。

function createArray<T>(length: number, value: T): Array<T> {
  const result: T[] = []
  for (let i = 0; i < length; i++) {
      result[i] = value
  }
  return result
}

以上就是一个泛型函数, T 代表任意类型。

泛型函数调用方式:

  1. 传入所有参数,包括类型参数
createArray<string>(3, 'x') // ['x', 'x', 'x']
  1. 利用类型推论,直接传入参数
createArray(3, 'x')

多个类型参数

实现一个函数,参数是长度为2、元素为任意类型的元组,返回位置交换后的元组。

function exchange<T, U>(tuple: [T, U]): [U, T] {
    return [tuple[1], tuple[0]]
}

exchange([7, 'sina']); // ['sina', 7]

通过类型别名定义泛型函数

type IGetArr<T> = (val: T, length: number) => T[]
const getArr: IGetArr<number> = (val: number, length: number = 3): number[] => {
  return Array(length).fill(val)
}
getArr('4', 5)

泛型约束

在泛型函数内部使用泛型变量时,由于我们预先并不知道它是哪种类型,所以不能随意操作其属性和方法(比如:获取泛型变量的length),但 T 不一定包含该属性,所以编译器会报错。

function getLength<T>(arg: T): T {
  console.log(arg.length) // Property 'length' does not exist on type 'T'.
  return arg
}

此时就需要对泛型变量进行约束,要求其必须包含length属性,这种操作我们称之为泛型约束。

定义接口来描述约束条件,并用 extends 关键字实现约束。

如下泛型函数的参数必须具有length属性:

interface restrainLength {
  length: number
}

function getLength<T extends restrainLength>(arg: T): T {
  console.log(arg.length) 
  return arg
}

多个参数时也可以在泛型约束中使用类型参数

多个参数的泛型函数,一个类型参数被另一类型参数所约束。

定义一个函数, 接受两个参数 第一个是对象 obj,第二个是第一参数对象中的key,返回 obj[key]。

使用 keyof 关键字约束。

function getValue<T, K extends keyof T>(obj: T, key: K) {
  return obj[key]
}

const obj = { a: 1, b: 2, c: 3 }
getValue(obj, 'a')
getValue(obj, 'd') //  Argument of type '"d"' is not assignable to parameter of type '"a" | "b" | "c"'.

泛型接口

可以通过接口的方式定义函数需要遵循的约束和规范。

interface IFoo {
  (name: string): string
}

let getInfo: IFoo = function(name: string): IFoo {
  return `the name is ${name}` 
}

这种方式不具有普适性,name的类型被限制死了。那么通过使用含有泛型的接口定义函数,如下:

interface IFoo {
  <T>(length: number, val: T): Array<T>
} 
const getArr: IFoo = function<T>(length: number, val: T): Array<T> {
  return Array(length).fill(val)
}
console.log(getArr(3, 'sian')) // ["sian", "sian", "sian"]

把泛型参数提前到接口名上,就可以知道使用的具体是哪个泛型类型,这样接口里的其他成员也能知道这个参数的类型。

interface IFoo<T> {
  (length: number, val: T): Array<T>;
} 

function getArr<T>(length: number, val: T): Array<T> {
  return Array(length).fill(val)
}

const getFoo: IFoo<string> = getArr
getFoo(3, 'sina')  // ['sina', 'sina', 'sina']

注意: 此时使用泛型接口时, 需要定义泛型的类型

泛型类

与泛型接口类似,泛型也可以用于类的类型定义中,泛型类使用 <> 括起泛型类型,跟在类名后面:

class Test<T> {
  foo: T
  constructor(foo: T) {
    this.foo = foo
  }
  echo(val: T): T {
    return val
  }
}

const test = new Test<number>(12)
test.echo(3)

泛型参数的默认类型

可以为泛型中的类型参数指定默认类型。当使用泛型时没有在代码中直接指定类型参数,从实际值参数中也无法推测出时,这个默认类型就会起作用。

function createArray<T = string>(length: number, value: T): Array<T> {
  let result: T[] = []
  for (let i = 0; i < length; i++) {
      result[i] = value
  }
  return result
}
createArray<number>(3, 3)

相关文章

  • TypeScript(六)泛型

    泛型是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。一般用于解决类、方法...

  • 2020-11-05Typescript(2.2)

    泛型 Generics---typeScript中最难的一部分 泛型 Generics---约束泛型 泛型 Gen...

  • TypeScript系列(六):泛型

    指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。 引入 下面创建一个函...

  • TS 泛型+装饰器

    typescript 中的泛型 泛型的定义泛型函数泛型类泛型接口 泛型:软件工程中,我们不仅要创建一致的定义良好的...

  • bunny笔记|TS基础(2):泛型函数、泛型约束、在泛型约束中

    01 typescript的操纵类型 02 03 04 泛型约束 05 在泛型约束中使用类型参数 06 在泛型中使...

  • 03_TypeScript学习(三)

    一. TypeScript枚举类型 二. 枚举类型的值 三. 认识泛型 四. 泛型实现类型参数化 五. 泛型的基本...

  • TypeScript 学习笔记4 泛型

    1.泛型 1.1 泛型函数 1.2 泛型类 1.3 泛型接口 Typescript从0到1-学习视频教程-培训课程...

  • typescript

    title: typescript学习tags: typescript学习 [toc] 泛型 基本使用 两种使用方...

  • TypeScript 泛型

    泛型函数 使用 数组 类 泛型约束

  • TypeScript泛型

    有时候编程还要考虑它的复用性,很多时候不需要指定它的类型,或者同样的方法逻辑 但是入参和出差的类型不同。这个时候就...

网友评论

    本文标题:TypeScript(六)泛型

    本文链接:https://www.haomeiwen.com/subject/iawfictx.html