TS中的泛型

typescript 中 最难的无疑是泛型(Generices), 那么泛型出现的动机是什么呢
思考一个问题: 泛型是怎样出现的,它要解决那些问题
现在有一个 echo 方法,传入什么类型的值返回什么类型的值

function echo(arg) {
	return arg
}
const result = echo(123)

result 返回值是一个 any 类型, 这不符合我们的预期, 那么指定入参和出参的类型,同样不符合预期, 这时候就用到泛型了

泛型(Generices)

定义

  • 定义函数,接口或类时,不预先指定具体类型,而是在使用的时候指定具体类型

使用

  • 在函数名称后面加一对尖括号,尖括号里面泛型名称(习惯写法为T,可以是任意名字),
  • 泛型名称可以看成是一个变量(也可以看作是一个占位符)
  • 泛型可以是任意类型在使用时指定即可
// 函数名后面插入尖括号,写入泛型名称T,参数和返回类型都是T
function echo<T>(arg:T):T {
	return arg
}
const str: string = '字符串'
// result 是 string 类型
const result = echo(str)
// 也可以不指定类型, ts 可以自动推断出类型
const result = echo(123) // 此时 result 为 number 类型

现在有个元组,里面有两个不同类型的值, 把这个元组传入 swap 方法中, 交换两个值的位置, 返回交换位置后的元组

// 根据上面需求我们实现下

// 定义元组
const tuple:[number,string] = [123,'str']

// swap 方法实现
function swap<T,U>(tuple:[T,U]):[U,T] {
	return [tuple[1],tuple[0]]
}

// 调用
const result = swap(tuple)

result[0]. 可以调用 字符串 的方法
result[1]. 可以调用 number 的方法

约束泛型

下面这个方法, 输出arg.length length下面有波浪线,出现了错误
在这里插入图片描述
下图提示: 泛型 T 不一定包含属性 length, 所以静态类型检查就会报错
在这里插入图片描述
那么这个函数接受的参数应该是有length属性的参数,使用 extends 关键字约束传入的泛型
使用 extends 使传入值满足约束条件

// 首先定义一个 IWithLength 的 interface
interface IWithLength {
	length: number
}
// 在 泛型名称T后面 使用 extends 关键字继承定义的 IWithLength 接口
function echoWithLength<T extends IWithLength>(arg:T):T {
	console.log(arg.length)
	return arg
}
// 验证下
const str = echoWithLength(`str`)
const obj = echoWithLength({a:1,b:'str'})
const arr = echoWithLength([1,2,3])

使用泛型描述类

新建一个队列类上实现两个方法,进入队列,离开队列, 这时候就可以使用泛型类

// 类名称后面传入泛型
class Queue <T>{
	private data:T[] = [];
	push(item:T) {
		return this.data.push(item)
	} 
	pop():T {
		this.data.shift()
	}
}
// 实例化 的时候传入想要的类型
const queue1 = new Queue<number>()
queue1.push(1)
console.log(queue1.pop().toFixed()) // 这里返回类型就是number可以使用 number 方法

// 实例化 的时候传入想要的类型
const queue2 = new Queue<string>()
queue1.push(`str`)
console.log(queue2.pop().length) // 这时可以调用 string 的方法

使用泛型描述对象

// 定义类型的时候 动态指定值 
interface KeyPair<T,U> {
	key: T;
	value: U;
}

let kp1: KeyPair<number,string> = { key: 123, value: 'str' }
let kp2: keypair<string,number> = { key: 'str', value: 123 }

使用泛型描述数组

定义一个number类型的数组

// 方法一
let arr2: Array<number> = [1,2,3]

// 方法二
interface Info {
	age: number
	name: string
}
let arr1: Info[] = [
	{age: 18, name: 'lili'},
	{age: 10, name: 'hihi'},
]

使用泛型描述函数

// 定义一个泛型接口
interface IPlus<T> {
	(a:T,b:T) : T
}
// 变量绑定类型
const plus: Iplus<number> = function (a,b){
	return a + b;
}
// number 类型
const a:Iplus<number> = plus(1,2)
// string 类型
const b:IPlus<string> = plus('hello','wold')

S中的类(class)

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gleason.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值