【TypeScript】TS进阶-泛型(八)

?个人主页:不叫猫先生
?‍♂️作者简介:前端领域新星创作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀!
?系列专栏:vue3从入门到精通、TypeScript从入门到实践
?资料领取:前端进阶资料以及文中源码可以找我免费领取
?社群招募:博主建立了一个前端交流群,汇集了各路大神,期待你的加入!(文末有我wx,或者私我)

目录

  • 专栏介绍
  • 泛型
    • 1、常用的泛型变量
    • 2、具体用法
      • (1)函数中多参数使用
      • (2)接口类型中使用
      • (3)类中使用
    • 3、泛型默认类型
    • 4、泛型约束
    • 5、泛型工具类型

专栏介绍

TypeScript从入门到实践专栏是博主在学习和工作过程中的总结,实用性非常强,内容会不断进行精进,欢迎订阅哦,学会TS不迷路。

TS系列 标题
基础篇 TS入门(一)
基础篇 TS类型声明(二)
基础篇 TS接口类型(三)
基础篇 TS交叉类型&联合类型(四)
基础篇 TS类型断言(五)
基础篇 TS类型守卫(六)
进阶篇 TS函数重载(七)
进阶篇 TS泛型(八)
进阶篇 TS装饰器(九)

泛型

软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。 ——摘自官方文档

为什么要引入泛型的概念呢?其实简单来讲就是为了实现复用,让模块可以支持多种类型数据 ,让类型声明和值一样,可以被赋值和传递。
泛型是什么呢?它可以说是一种类型占位符,也可以说是类型变量,需要注意的是它一种特殊的变量,只用于表示类型而不是值。我们在定义函数、接口或类的时候,不预先指定具体类型,而是在使用的时候再指定类型,先站住位置再说,保证了输入输出保持一致的问题。
这里举个例子说明为什么要使用泛型。我们写一个函数实现返回传递参数的值,并且打印这个值,参数类型为string,返回值类型也是string,保证输入输出保持一致。

function result(val:string):string {
    console.log(val)
    return val
}

当然我们可以用any来定义变量类型,如下:

function result(val:any):any {
    console.log(val)
    return val
}

因为any是任意类型,所以我们不能保证输入输出保持一致,比如参数类型是number,返回的却是string,另外最好不要用any。
如果我参数类型是number,返回值类型也是number,我们就需要再写一个函数,是不是有点重复了,如果参数类型,返回值类型可以是个类型变量,可以根据传递的值来判断是不是就方便很多啦,比如下面写的这个例子,看不懂没关系,下面详细解析:

function result<T>(val:T):T {
    console.log(val)
    return val
}
result(<string>"zhangsan")

result函数添加一个类型变量TT需要写在<>T帮助我们捕获用户传入的类型(比如:number), 之后我们再次使用了 T当做返回值类型。这样参数类型和返回值类型就相同啦。编译为JS的代码如下:

function result(val) {
    console.log(val);
    return val;
}
result("zhangsan");

下面详细讲解下用法。

1、常用的泛型变量

  • T(Type) :代表类型,定义泛型时通常作为第一个类型变量名称
  • K(Key):表示对象中的键类型
  • U:表示对象中的键类型
  • V(Value):表示对象中的值类型
  • E(Element):表示元素或者节点类型

2、具体用法

(1)函数中多参数使用

function startClass <T, U>(name: T, score: U) : T {
    return name + score;
 }
console.log(startClass<String, Number>("zhangsan", 5));//zhangsan5

(2)接口类型中使用

interface  Class{
    <T,U>(name:T,score:U):T
}
let func = function <T,U>(name:T,score:U):T{
    return name + ':'+ score
}
func('zhangsan',3)//编译器自动识别参数类型,作为泛型的类型

(3)类中使用

class Animal<T> {
 name:T;
 constructor(name: T){
  this.name = name;
 }
 get<T>(say:T) {
   console.log(say)
 }
}
let animal = new Animal('cat');
animal.get('pig')//pig

3、泛型默认类型

语法:<T = default type>

 function result<T=string>(val:T):T {
    console.log(val.length)
    return val
}

4、泛型约束

我们之间使用属性方法,但是不知道类型就会报错,所以需要对参数类型进行约束。

 function result<T>(val:T):T {
    console.log(val.length)
    return val
}
result(<string>"zhangsan")
//这种写法也可以的哦
//result<string>("zhangsan")

在这里插入图片描述
怎么进行约束呢?先用type声明一个变量类型,让类型变量T继承接口Class ,此时代码就不会报错啦。

type Class = string;
function result<T extends Class>(val:T):T {
  console.log(val.length)
  return val
}
result(<string>"zhangsan")

在这里插入图片描述
当然我们也可以使用接口类型,让变量类型T继承接口Class,具体如下:

interface Class{
    name:string,
    age:number
}
function result<T extends Class>(val:T):T {
  console.log(val.name)
  return val
}
result({name:"zhangsan",age:10})
//如果参数重不写age的话,就会报错
//类型“{ name: string; }”的参数不能赋给类型“Class”的参数。
//类型 "{ name: string; }" 中缺少属性 "age",但类型 "Class" 中需要该属性。
result({name:"zhangsan"})

如果不对变量类型进行约束的话,还是会报错滴,如下:
在这里插入图片描述

5、泛型工具类型

后续更新泛型工具类型文章来源地址https://uudwc.com/A/9v5PV

原文地址:https://blog.csdn.net/qq_38951259/article/details/128556396

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

h
上一篇 2023年08月16日 10:15
〔AI 绘画〕Stable Diffusion 之 界面参数和基础使用 篇
下一篇 2023年08月16日 10:16