首页IT科技泛型中的通配符(TypeScript(7)泛型)

泛型中的通配符(TypeScript(7)泛型)

时间2025-05-01 17:02:15分类IT科技浏览4129
导读:泛型 指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。...

泛型

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

引入

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

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个参数value和count                ,返回any类型的数组      ,然后定义了一个any类型的空数组arr                 。接下来我们查看结果

在编译阶段我们没有报错是因为      ,我们把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(value: T, count: number): T[]           ,函数createArray和value参数和返回类型都由用户自己决定      。

const arr1 = createArray<number>(11, 3)这句代码是没问题                 ,因为规定了number类型      ,传入的也是number

当我们将代码修改成如下代码:

我们发现报错了           ,因为规定了number类型                ,传入的却是字符串11      ,

当我们输入如下代码      ,也会报错

报错原因如下

所以如果我们使用了泛型                ,就会避免类型输入错误或者用错方法

多个泛型参数的函数

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

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属性

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
苹果电脑如何访问共享文件夹(苹果系统如何访问Windows共享文件夹?Mac访问Windows共享文件夹的方法) 怎么用mac格式化u盘(苹果系统怎么格式化U盘?MAC格式化U盘的方法)