【TypeScript】TS泛型讲解及其使用

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 【TypeScript】TS泛型讲解及其使用,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

目录

泛型

泛型函数使用

泛型约束

多泛型使用

泛型接口

泛型类

泛型工具类型


泛型

泛型是可以在保证类型安全的前提下,让函数等与多种类型一起工作,从而实现复用,常用于:函数、接口、class中。日常我们创建的函数,传入什么数据就返回什么数据本身,即参数与返回值的类型相同,如下:

function add(value: number): number{
  return value
}

而为了能够让函数接收任何类型,我们以前可以将参数类型修改为any。但这样就失去了TS的类型保护,类型不安全,泛型在保证类型安全的同时(不丢失类型信息),可以让函数与多种不同的类型一起工作,灵活可复用。

泛型函数使用

创建泛型函数:我们在创建函数的同时在函数名称后面添加 <> (尖括号),尖括号中添加类型变量,如下:

当然创建泛型函数的类型变量可以是任意合法变量名称,不仅仅是下面例子中的type。

// 类型变量 type 是一种特殊类型的变量,它只处理类型不处理值。
// 该类型变量相当于一个类型容器,能够捕获用户提供的类型(具体类型由用户调用函数时指定)
function add<type>(value: type): type{
  return value
}

调用泛型函数

在调用函数的同时在函数后面声明自己要传入参数的类型,用 <> 进行包裹。

// 创建泛型函数
function add<type>(value: type): type{
  return value
}
// 调用泛型函数
const num = add<number>(10) // 以 number 类型调用函数
const str = add<string>('s') // 以 string 类型调用函数
const ret = add<boolean>(true) // 以 boolean 类型调用函数

当然在调用泛型函数时,可以省略<类型>来简化泛型函数的调用。因为TS内部会采用一种叫做类型参数推断的机制,来根据传入的参数自动推断出类型变量的类型。使用这种简化的方式调用泛型函数,使代码更短更便于阅读。

注意:当编译器无法推断类型或者推断的类型不准确时,就需要显式地传入类型参数。

【TypeScript】TS泛型讲解及其使用

泛型约束

默认情况下,泛型函数的类型变量可以代表多个类型,这就导致无法访问任何属性。比如当我们需要获取字符串长度时使用泛型就会报错,因为泛型代表任意类型无法保证一定存在某个属性,此时就需要为泛型 添加约束 缩窄类型取值范围

添加泛型约束收缩类型主要有以下两种方式:

指定更具体的类型:可以根据自身需要将泛型函数的类型修改来获取属性,如下:

// 创建泛型函数
function add<type>(value: type[]): type{
  console.log(value.length)
  return value
}

添加约束:可以创建描述约束的接口来提供自己的属性,通过 extends 关键字为类型变量添加约束

interface MyLength {length:number}
// 创建泛型函数
function add<type extends MyLength>(value: type): type{
  console.log(value.length)
  return value
}
add([1,2])
add('123')
add({name:'张三',length:12,age:13})

多泛型使用

泛型的类型变量可以有多个,并且类型变量之间还可以约束(比如:第二个类型变量受第一个类型变量约束)。案例如下:

// 创建泛型函数
// keyof关键字接收一个对象类型,生成其键名称(或字符串或者数字)的联合类型
function add<type,key extends keyof type>(obj: type,value: key) {
  return obj[value]
}
add(18,"toString")
add({name:'张三',age:18},"name")

【TypeScript】TS泛型讲解及其使用

泛型接口

接口的名称后面添加 <类型变量> ,那么这个接口就变成了泛型接口。接口也可以搭配泛型来使用,以增加其灵活性,增强其复用性。

interface person<type> {
  id: (value:type) => type
  ids: ()=> type[]
}
// 使用泛型接口时一定要显式指定具体类型,否则报错
let p: person<number> ={
  id(value){
    return value
  },
  ids() {
    return [1,2,3]
  },
}

泛型类

class也可以配合泛型来使用。

创建泛型类

类似于泛型接口,在class名称后面添加<类型变量>,这个类就变成了泛型类。

class Animals<type> {
  defaultValue: type
  say: (x: number,y :number) => type
  constructor(value: type){
    this.defaultValue = value
  }
}
// 当我们提供 constructor 并且里面已经提供类型了,这个时候我们new实例的时候,类型可以省略。
// const num = new Animals<number>(10)
const num = new Animals(10)

泛型工具类型

TS内置了一些常用的工具类型,来简化TS中的一些常见操作。它们都是基于泛型实现的,并且都是内置的,可以直接在代码中使用。这些工具类很多,主要学习以下几个:

Partial<type>:用来构造一个类型,将type的所有属性设置为可选。

interface People {
  name: string
  age: number
  hobby: number[]
}
// 使的接口属性变为可选属性
type commenPeople = Partial<People>
// 调用接口,属性一定必须
let p1: People = {
  name:'张三',
  age:18,
  hobby:[1,2]
}
// 使用 Partial 使的接口属性变为可选
let p2: commenPeople = {
  name:''
}

Readonly<type>:用来构造一个类型,将type的所有属性都设置为 readonly (只读)。

interface People {
  name: string
  age: number
  hobby: number[]
}
// 使的接口属性变为可选属性
type ReadonlyPeople = Readonly<People>
// 调用接口,属性一定必须
let p1: ReadonlyPeople = {
  name:'张三',
  age:18,
  hobby:[1,2]
}
// 无法分配到 "name" ,因为它是只读属性。
// p1.name = '李四' 

Pick<type,keys>:从type中选择一组属性来构造新类型。 Pick工具类型有两个类型变量:第一个表示选择谁的属性;第二个表示选择哪几个属性。注意:第二个类型变量传入的属性只能是第一个类型变量中存在的属性。

interface People {
  name: string
  age: number
  hobby: number[]
}
// 使的接口属性变为可选择属性
type RickPeople = Pick<People,'name'|'hobby'>
// 调用接口,属性一定必须
let p1: RickPeople = {
  name:'张三',
  // 对象文字可以只指定已知属性,并且“age”不在类型“RickPeople”中。
  // age:18,
  hobby:[1,2]
}

Record<keys,type>:构造一个对象类型,属性键位keys,属性值为type。

type RecordObj = Record<'a'|'b'|'c',string[]>
let obj: RecordObj = {
  a:['1'],
  b:['1'],
  c:['1']
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/140019.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!