写点什么

一文带你了解 TypeScript 泛型

作者:程序员海军
  • 2023-04-25
    上海
  • 本文字数:1901 字

    阅读完需:约 6 分钟

一文带你了解 TypeScript 泛型


什么是泛型

我们先来看看 ChatGPT 怎么说:



:::success 泛型就是 将类型进行传递,然后确保在使用的时候类型正确。:::

泛型优缺点

优点


  1. 类型安全:使用泛型可以让代码在编译时就发现类型错误,避免了运行时类型错误的发生。

  2. 代码复用:泛型可以将一些通用的代码封装成可复用的函数或类,避免了重复编写类似的代码。

  3. 可读性较好:使用泛型可以增强代码的可读性和可维护性,使代码更加易于理解和修改。

  4. 提高性能:泛型 代码在 TypeScript 中不需要进行额外的类型检查和类型转换,可以提高程序的运行效率。


缺点


  1. 学习曲线陡峭:与 Java 中一样,使用泛型需要掌握类型参数、泛型方法和通配符等概念,这可能会使初学者感到困惑。

  2. 约束较强:在 TypeScript 中,泛型的类型参数需要满足一定的约束条件,这可能会限制泛型的使用范围和灵活性。

  3. 限制了某些操作:与 Java 中类似,在 TypeScript 中使用泛型时,由于类型参数的不确定性,有些操作是不支持的,例如创建泛型数组、使用 instanceof 运算符等。

  4. 需要考虑类型擦除:与 Java 中类似,泛型在 TypeScript 中也是通过类型擦除实现的,这可能会影响一些泛型代码的实现和设计。


泛型格式

泛型 用 <> 符号标识泛型类型, 一般是 T 作为 泛型变量 。


  1. 下面代码中,我们定义一个 获取数据的方法 getData ,给它传入了 泛型变量 T, 参数类型也是 T, 返回值的类型也是 T


function getData<T>(data : T): T {    return data}
复制代码


  1. 调用函数:::success 它有两种调用方式:

  2. 直接调用,传入参数, 编译器会进行类型推理

  3. 传入指定类型,然后输入的参数必须和指定的类型一致,不然会报错



:::


type UserInfo =  {    id:Number,    name:String,    address:String,}

interface EmailInfo { to:String, from:String, content:String, time:Date}
function getData<T>(data : T): T { return data}
console.log(getData("测试"))// 测试
console.log(getData<UserInfo>({id:1,name:"海军",address:"上海"}))// { id: 1, name: '海军', address: '上海' }
console.log(getData<EmailInfo>({to:'Amy',from:"John",content:"最近过的好吗",time: new Date()}))
// {// to: 'Amy',// from: 'John',// content: '最近过的好吗',// time: 2023-04-16T13:52:26.026Z// }
复制代码

泛型接口

:::success 泛型接口可以这样理解:当你需要给接口指定类型时,但目前不知道属性类型为什么时,就可以采用泛型接口你可以给接口指定参数为多个泛型类型,也可以单个;当使用时,明确参数类型即可。:::



interface GenericIdentityFn<T,S,D> {    id: T,    source:S,    url: D}   
const websiteInfo : GenericIdentityFn<Number,String,String> = {id:2212,source:"爬虫",url:"http://www.sadasd.com"}
console.log(websiteInfo)
// { id: 221241234, source: '爬虫', url: 'http://www.sadasd.com' }
复制代码

泛型类

什么是泛型类

它规定了类中属性和方法的 类型,而且必须和类型定义的类型保持一致。

泛型类的作用

可以帮助我们确认类的所有属性都在使用相同的类型

使用格式

class 类名<T> { name!: T; hobby!: T;}
# 这样这个类的所有类型为 numberlet 实例 = new 类名<number>();



class GenericityA<X>{ sex!: X; age!: X;}

let gen = new GenericityA<number>();
// gen.sex = '测试' 报错gen.age = 3console.log(gen.age)
复制代码

泛型约束

接口约束

通过定义接口, 泛型函数继承接口,则参数必须实现接口中的属性,这样就达到了泛型函数的约束。


# 第一种// 定义接口 interface DataInfo{     title: string,     price: number }

// 泛型函数 继承接口,进行对参数类型约束, 如果传入的参数中,没有包含接口属性,则编译不通过 function getDataInfos< T extends DataInfo> (obj: T) : T { return obj }
let book = { title: '前端进阶', price: 50, author: '小新' }
console.log(getDataInfos(book)) //{ title: '前端进阶', price: 50, author: '小新' }


复制代码

类约束

通过给类的泛型指定为另一个类,这样就规定了类泛型的类型都为另一个类


# 第二种//  通过类来约束 class Login{    username: string;    password: string;    constructor(username: string,password:string){        this.username = username        this.password = password    } }
class Mysql<T>{ login<T>(info:T):T{ return info }}
let x = new Login('admin','12345');let mysql = new Mysql<Login>();console.log(mysql.login(x)) //Login { username: 'admin', password: '12345' }
复制代码


发布于: 20 小时前阅读数: 19
用户头像

🏆微信公众号:【前端自学社区】 2020-04-02 加入

🏅目前从事物流,铁路相关的前端全栈开发工作. 🏆 InfoQ 首批签约作者 🏆荣获2021/2022年度社区共建奖 😊个人微信: daxin261

评论 (1 条评论)

发布
用户头像
欢迎一起交流讨论学习!
19 小时前 · 上海
回复
没有更多了
一文带你了解 TypeScript 泛型_typescript_程序员海军_InfoQ写作社区