typescript的泛型_泛型有什么用

typescript的泛型_泛型有什么用泛型指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。引入下面创建一个函数,实现功能:根据指定的数量count和数据value,创建一个包

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

泛型

指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。
 

引入

下面创建一个函数, 实现功能: 根据指定的数量 count 和数据 value , 创建一个包含 countvalue 的数组 不用泛型的话,这个函数可能是下面这样:

function createArray(value: any, count: number): any[] {
    const arr: any[] = []
    for (let index=0; index < count; index++) {
        arr.push(value)
    }
    return arr
}

const arr1 = createArray('a', 3)
const arr2 = createArray(1, 3)
console.log(arr1)
console.log(arr2)
console.log(arr1[0].toFixed(), arr2[0].split(''))

我们创建了一个函数createArray,传入2个参数valuecount,返回any类型的数组,然后定义了一个any类型的空数组arr。接下来我们查看结果
typescript的泛型_泛型有什么用
在编译阶段我们没有报错是因为,我们把value设置为了any类型,但是当编译完成后运行时,arr1是字符串,字符串是没有toFixed方法的,所以会报错,那么我们希望在编译阶段就报错,就可以使用泛型
 

使用泛型

// 使用函数泛型
function createArray<T>(value: T, count: number): T[] {
    const arr: Array<T> = []
    for (let index=0; index < count; index++) {
        arr.push(value)
    }
    return arr
}
const arr1 = createArray<number>(11, 3)
console.log(arr1[0].toFixed())
const arr2 = createArray<string>('AA', 3)
console.log(arr2[0].split(''))
console.log('---------')
console.log(arr2[0].toFixed())  // 报错,因为字符串没有toFixed方法
console.log(arr1[0].split(''))  // 报错,因为number没有split方法

泛型的意思就是类型由用户自己决定,比如function createArray<T>(value: T, count: number): T[],函数createArrayvalue参数和返回类型都由用户自己决定。
const arr1 = createArray<number>(11, 3)这句代码是没问题,因为规定了number类型,传入的也是number
 
当我们将代码修改成如下代码:
typescript的泛型_泛型有什么用
我们发现报错了,因为规定了number类型,传入的却是字符串11
typescript的泛型_泛型有什么用
当我们输入如下代码,也会报错
typescript的泛型_泛型有什么用
报错原因如下
typescript的泛型_泛型有什么用
所以如果我们使用了泛型,就会避免类型输入错误或者用错方法
 

多个泛型参数的函数

一个函数可以定义多个泛型参数

function swap <K, V> (a: K, b: V): [K, V] {
  return [a, b]
}
const result = swap<string, number>('abc', 123)
console.log(result[0].length, result[1].toFixed())

 

泛型接口

interface IbaseCRUD <T> {
    // 定义泛型数组data
    data: T[]
    add: (t: T) => void
    getById: (id: number) => T
}

class User {
    id?: number;
    name: string;
    age: number;

    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}

class UserCRUD implements IbaseCRUD<User> {
    data: User[] = []

    add(user: User): void {
        user = {...user, id: Date.now()}
        this.data.push(user)
        console.log('保存user', user.id)
    }

    getById(id: number): User {
        return this.data.find(item => item.id === id)
    }
}


const userCRUD = new UserCRUD()
userCRUD.add(new User('tom', 12))
userCRUD.add(new User('tom2', 13))
console.log(userCRUD.data)

 

泛型类

泛型类看上去与泛型接口差不多。 泛型类使用( <>)括起泛型类型,跟在类名后面。

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

GenericNumber类的使用是十分直观的,并且你可能已经注意到了,没有什么去限制它只能使用number类型。 也可以使用字符串或其它更复杂的类型。

let stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "";
stringNumeric.add = function(x, y) { return x + y; };

console.log(stringNumeric.add(stringNumeric.zeroValue, "test"));

与接口一样,直接把泛型类型放在类后面,可以帮助我们确认类的所有属性都在使用相同的类型。
 

泛型约束

如果我们直接对一个泛型参数取 length 属性, 会报错, 因为这个泛型根本就不知道它有这个属性

// 没有泛型约束
function fn <T>(x: T): void {
  console.log(x.length)  // 报错,因为目前不知道x是什么类型
}

我们可以使用泛型约束来实现

interface Lengthwise {
  length: number;
}

// 指定泛型约束
function fn2 <T extends Lengthwise>(x: T): void {
  console.log(x.length)
}

我们需要传入符合约束类型的值,必须包含必须 length 属性:

fn2('abc')
// fn2(123) // error  number没有length属性
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/165337.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • noip2014普及组初赛答案_观光3路公交车路线

    noip2014普及组初赛答案_观光3路公交车路线话说,我终于AC了这个题这是一个贪心,说实话开始做的时候……完全没看出来QAQ。。可能有人说这是个dp,但这真不是(dalao请无视)这真的只是个贪心。。。。首先对于每个点当然是能走就走,不能走就等待,这是无法控制的。所以只考虑氮气加速器加在哪里可以使时间总和尽量少。所以如果选择加速,可能会使后面等待的时间更长,或者更短,对后面都会有影响。但是沿着一条边加速会影响后面的所…

    2022年9月24日
    2
  • python表白代码大全简单-python表白代码

    python表白代码大全简单-python表白代码广告关闭腾讯云双11爆品提前享,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高满返5000元!作者|马超编辑|jane来源|csdn博客【导语】转眼又到了咱们中国传统的情人节七夕了,今天笔者就带大家来领略一下用python表白的方式。让程序员的恋人们感受一下it人的浪漫。一、词云制作首先咱们可以用之前介绍过的wordcould包制作词云。wordc…

    2022年6月2日
    46
  • 什么是dom_字母圈术语大全

    什么是dom_字母圈术语大全DOM概述html加载完毕,渲染引擎会在内存中吧html文档生成一个DOM树,getElementById是获取DOM上的元素,然后操作的时候修改的该元素的属性什么是DOM和节点1、DOM由

    2022年8月4日
    8
  • dreamweaver导入站点_站点创建成功咋办

    dreamweaver导入站点_站点创建成功咋办
    在“文件”面板中,单击“文件”下方列表框的下拉箭头,从下拉列表框中单击“管理站点”菜单项,如下图所示。
    弹出“管理站点”对话框,如下图所示。
    点击“新建”-“站点”,如下图所示。
    弹出“未命名站点1的站点定义为”对话框,在“基本”选项卡,“您打算为您的站点起什么名字?”一栏输入站点的名字,如:Fuersen。在“您的站点的HTTP地址(URL)是什么?”输入“http://www.Fuersen.com/mysite”,如下图所示。
    点击“下

    2022年10月21日
    3
  • IntelliJ IDEA Community Edition 社区版插件汇总「建议收藏」

    IntelliJ IDEA Community Edition 社区版插件汇总「建议收藏」一、前言今年Idea对盗版软件打击力度加大,朋友们会发现,旗舰版自己激活使用,过几天就会失效,需要重新激活,有的小伙伴就会选择去淘宝花钱买个教育邮箱注册,这个方法我使用过,过了两三个月就不能用了,着实让人头疼。如何解决呢?我想到了Idea社区版本,下载一个使用,将我的Springboot项目导入,启动下试试,不出所料,报错了。好啦!步入正题。社区版Idea相比旗舰版少了很多功能,包括Java开发最重要的Web开发能力!Spring项目没有Tomcat插件,不能在Idea启动。SpringBoot

    2022年9月15日
    0
  • 抓包工具charles的https抓包配置

    抓包工具charles的https抓包配置PC端安装ssl证书单击安装证书 单击下一步,修改证书存储路径,如下图单击下一步直到完成  手机客户端安装证书手机浏览器访问地址证书下载地址:http://www.charlesproxy.com/documentation/using-charles/ssl-certificates/https://www.charlesproxy.com/docum…

    2022年5月30日
    36

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号