ts中的泛型

本文深入介绍了TypeScript的泛型概念,包括在函数、接口和类中如何使用泛型,以及泛型的意义。通过示例展示了如何在函数中定义和调用泛型,以及在接口和类中应用泛型。此外,还讲解了泛型约束,特别是使用接口约束泛型的场景,强调了泛型在确保类型安全和代码复用中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

泛型简单介绍

  1. 泛型是什么

    泛型指的是在定义函数/接口/类型时,不预先指定具体的类型,而是在使用的时候指定类型限制的一种特性

  2. 泛型的意义(目的)

    设计泛型的关键目的是在成员之间提供有意义的约束。

这些成员可以是:类的实例成员、类的方法、函数参数和函数返回值。

泛型的使用

泛型的写法就是在标志符后面添加尖括号(<>),然后在尖括号里写形参,并在 body(函数体, 接口体或类体) 里用这些形参做一些逻辑处理。

1. 在函数中使用泛型

//添加类型变量T,T帮助我们捕获用户传入的类型(比如:number)
//参数类型为T,返回值类型为T
function fun1<T>(x: T): T {
    return x;
}
//这里传入T为string类型
fun1<string>('a')

//这里传入T为number类型
fun1<number>(123)

2. 接口中使用泛型

首先是ts接口写法

interface IInfo {
    name: string
    age?: number // 可选类型
}

const info: IInfo = {
    name: 'james',
    age: 20
}

info.age // ok
info.name // ok

在接口中使用到泛型的写法

// 可以同时传入多个类型
interface User<T, N> {
    name: T,
    age: N
} 


const user: User<string, number> = {
    name: 'hsh',
    age: 18
}

user.name // ok
user.age // ok

3. 在类中使用泛型

在类中使用泛型也很简单,我们只需要在类名后面,使用 <T, …> 的语法定义任意多个类型变量

interface GenericInterface<U> {
  value: U
  getIdentity: () => U
}

class IdentityClass<T> implements GenericInterface<T> {
  value: T

  constructor(value: T) {
    this.value = value
  }

  getIdentity(): T {
    return this.value
  }

}

const myNumberClass = new IdentityClass<Number>(68);
console.log(myNumberClass.getIdentity()); // 68

const myStringClass = new IdentityClass<string>("Semlinker!");
console.log(myStringClass.getIdentity()); // Semlinker!

implements也是实现父类和子类之间继承关系的关键字,如类 A 继承 类 B 写成 class A implements B{}.

implements是一个类实现一个接口用的关键字,他是用来实现接口中定义的抽象方法。
比如:people是一个接口,他里面有say这个方法。public interface people(){ public say();}但是接口没有方法体。
只能通过一个具体的类去实现其中的方法体。比如chinese这个类,就实现了people这个接口。
public class chinese implements people{ public say() {System.out.println(“你好!”);}}

接下来以实例化 myNumberClass 为例,来分析一下其调用过程:

在实例化 IdentityClass 对象时,我们传入 Number 类型和构造函数参数值 68;
之后在 IdentityClass 类中,类型变量 T 的值变成 Number 类型;
IdentityClass 类实现了 GenericInterface<T>,而此时 T 表示 Number 类型,因此等价于该类实现了 GenericInterface<Number> 接口;
而对于 GenericInterface<U> 接口来说,类型变量 U 也变成了 Number。
这里我有意使用不同的变量名,以表明类型值沿链向上传播,且与变量名无关。
泛型类可确保在整个类中一致地使用指定的数据类型。

泛型约束

使用接口约束泛型

interface Person {
  name:string;
  age:number;
}
function student<T extends Person>(arg:T):T {
  return arg;
}

student({name:'lili'});//类型 "{ name: string; }" 中缺少属性 "age",但类型 "Person" 中需要该属性
student({ name: "lili" , age:'11'});//不能将类型“string”分配给类型“number”
student({ name: "lili" , age:11});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值