🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] >[success] # 泛型(Generics) 第二部分 - 约束泛型 上一章我们介绍了 **泛型** 出现的动机,要解决什么问题,和 **泛型** 的一个 **简单的用法** ,可以把它看成是一个 **占位符** ,在 **使用时** 才动态的填入 **确定类型值** ,本章将探讨 **泛型** 更深入的用法。 <br> 我们来谈谈 **约束泛型** ,为什么会有这个概念呢?来举个例子,我们下面新建一个 **echowichArr 函数** ,给添加一个 **arg参数** ,然后添加上 **泛型** ,代码如下: **index.ts** ~~~ function echowichArr<T>(arg: T): T { console.log(arg.length) return arg } ~~~ **编辑器图片**: ![](https://img.kancloud.cn/c7/c8/c7c851d8d4b30938b2c52ecb89a6493f_734x200.png) 这时会发现编辑器抛出了一个错误,因为在 **函数内部使用泛型变量** 时,由于 **事先不知道它是哪种类型,所以不能随意的来操作它的属性或方法** ,这里就报一个错误,意思是:**泛型T 不一定包含属性 length** ,我们可以给这个函数 **传入任意类型数据 ,当然有些数据不包括 length属性** ,所以编译时就报错了,那么我们给这个 **函数** 传入个 **数组** 作为 **参数**,这样就有 **length属性** 了,代码如下: **index.ts** ~~~ function echowichArr<T>(arg: T[]): T[] { console.log(arg.length) return arg } const arrs = echowichArr([1,2,3]) ~~~ **编辑器图片**: ![](https://img.kancloud.cn/60/65/6065781f9aa018cd8a2b1776cec45b27_436x181.png) 可以看到 **arrs** 可以正确的返回 **number数组** ,但是这个解决方案不是完美的, **我们只能传入数组** ,可能 **对象** 中有我们自己定义的属性,起名为 **length** ,再或者 **string** 类型数据也是有 **length** 属性的,我们传入 **string** 类型数据就会报错,代码如下: **index.ts** ~~~ function echowichArr<T>(arg: T[]): T[] { console.log(arg.length) return arg } const arrs = echowichArr('str') ~~~ **编辑器图片**: ![](https://img.kancloud.cn/bb/08/bb08369e70ec87a5e7698ea28ecd38cb_1062x143.png) 此时编辑器抛出了一个错误,意思是 **str 不能赋值给一个 array 类型** ,所以我们需要一个新的解决方案, **我们可以对泛型进行一个约束,只允许这个函数传入包含 length 属性的变量,这就是约束泛型** >[success] ## 约束泛型 总结: 在 **泛型** 中使用 **extends** 关键字,就 **可以让传入值满足我们特点的约束条件,而不是想传入啥就传入啥**。 首先我们创建一个 **接口(interFace)** ,来 **约束传入的数据的类型** ,代码如下: **index.ts** ~~~ // 定义接口(用来约束数据类型) interface IWithLength { length: number } // 约束传入的泛型 function echowichLength<T extends IWithLength>(arg: T): T { console.log(arg.length) return arg } // 传入 string 类型数据 const str = echowichLength('str') // 传入 object 类型数据,并且属性名称定义未length const obj = echowichLength({ length: 10, width: 10 }) // 可以有更多的属性,但是必须要包括 length // 传入 array 类型数据 const arr = echowichLength([1, 2, 3]) // 错误示例 echowichLength(123) ~~~ **编辑器图片**: ![](https://img.kancloud.cn/87/0f/870f3167d7d7327a43891f049f5a74ec_1067x457.png) 这里是提示 **123** 里没有 **length属性** 。