TypeScript系列教程六《泛型》(2)

本文讨论了JavaScript中泛型的使用,包括如何在函数和类中传递数组,以及如何通过泛型约束确保类型安全。作者解释了泛型接口、泛型类的区别,并展示了如何通过接口和约束处理具有特定属性的类型参数。
摘要由CSDN通过智能技术生成

假如我想泛型传入数组,在泛型函数里面遍历数组,是不是type可以代表数组,可以使用数组的length属性?

测试:

function loggingIdentity(arg: Type): Type {

console.log(arg.length);

//Property ‘length’ does not exist on type ‘Type’.

return arg;

}

答案是否定的。

我们需要在泛型函数参数声明数组:

function loggingIdentity(arg: Array): Array {

console.log(arg.length); // Array has a .length, so no more error

return arg;

}

或者

function loggingIdentity(arg: Type[]): Type[] {

console.log(arg.length);

return arg;

}

泛型类型



泛型函数的类型与非泛型函数的类型没什么不同,只是有一个类型参数在最前面,像函数声明一样:

function identity(arg: T): T {

return arg;

}

let myIdentity: (arg: T) => T = identity;

我们也可以使用不同的泛型参数名,只要在数量上和使用方式上能对应上就可以。

function identity(arg: T): T {

return arg;

}

let myIdentity: (arg: U) => U = identity;

这引导我们去写第一个泛型接口了。 我们把上面例子里的对象字面量拿出来做为一个接口:

interface GenericIdentityFn {

(arg: T): T;

}

function identity(arg: T): T {

return arg;

}

let myIdentity: GenericIdentityFn = identity;

一个相似的例子,我们可能想把泛型参数当作整个接口的一个参数。 这样我们就能清楚的知道使用的具体是哪个泛型类型(比如: Dictionary而不只是Dictionary)。 这样接口里的其它成员也能知道这个参数的类型了。

interface GenericIdentityFn {

(arg: T): T;

}

function identity(arg: T): T {

return arg;

}

let myIdentity: GenericIdentityFn = identity;

除了泛型接口,我们还可以创建泛型类。 注意,无法创建泛型枚举和泛型命名空间。

泛型类



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

class GenericNumber {

zeroValue: NumType;

add: (x: NumType, y: NumType) => NumType;

}

let myGenericNumber = new GenericNumber();

myGenericNumber.zeroValue = 0;

myGenericNumber.add = function (x, y) {

return x + y;

};

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

let stringNumeric = new GenericNumber();

stringNumeric.zeroValue = “”;

stringNumeric.add = function(x, y) { return x + y; };

console.log(stringNumeric.add(stringNumeric.zeroValue, “test”));

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

我们在类那节说过,类有两部分:静态部分和实例部分。 泛型类指的是实例部分的类型,所以类的静态属性不能使用这个泛型类型。

泛型约束



你应该会记得之前的一个例子,我们有时候想操作某类型的一组值,并且我们知道这组值具有什么样的属性。 在 loggingIdentity例子中,我们想访问arg的length属性,但是编译器并不能证明每种类型都有length属性,所以就报错了。

function loggingIdentity(arg: T): T {

console.log(arg.length); // Error: T doesn’t have .length

return arg;

}

相比于操作any所有类型,我们想要限制函数去处理任意带有.length属性的所有类型。 只要传入的类型有这个属性,我们就允许,就是说至少包含这一属性。 为此,我们需要列出对于T的约束要求。

为此,我们定义一个接口来描述约束条件。 创建一个包含 .length属性的接口,使用这个接口和extends关键字来实现约束:

interface Lengthwise {

length: number;

}

function loggingIdentity(arg: T): T {

console.log(arg.length); // Now we know it has a .length property, so no more error

return arg;

}

现在这个泛型函数被定义了约束,因此它不再是适用于任意类型:

loggingIdentity(3); // Error, number doesn’t have a .length property

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

loggingIdentity({length: 10, value: 3});

在泛型约束里使用类型参数

您可以声明受另一个类型参数约束的类型参数。 例如,这里我们想从一个给定名称的对象中获取一个属性。 我们想确保我们不会意外地获取 obj 上不存在的属性,因此我们将在两种类型之间放置一个约束:

function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {

return obj[key];

}

let x = { a: 1, b: 2, c: 3, d: 4 };

getProperty(x, “a”);

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

更多面试题

**《350页前端校招面试题精编解析大全》**内容大纲主要包括 HTML,CSS,前端基础,前端核心,前端进阶,移动端开发,计算机基础,算法与数据结构,项目,职业发展等等

资料获取方式:点击蓝色传送门免费获取

…(img-9aO44hw2-1713562295590)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

[外链图片转存中…(img-NC4vnLF4-1713562295590)]

更多面试题

**《350页前端校招面试题精编解析大全》**内容大纲主要包括 HTML,CSS,前端基础,前端核心,前端进阶,移动端开发,计算机基础,算法与数据结构,项目,职业发展等等

资料获取方式:点击蓝色传送门免费获取

[外链图片转存中…(img-jktXyPnS-1713562295590)]

  • 27
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值