TypeScript泛型应用

简介: TypeScript泛型应用

概念:


泛型程序设计(generic programming)是程序设计语言的一种风格或范式。泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。


泛型应用:



场景:在做前后端交互数据接口统一返回格式定义的场景来进行泛型的实战训练。

  1. 通过ID查询指定数据返回的报文格式:

1.png

  1. 通过查询整个列表返回的报文格式:

2.png


通过分析两份返回报文可以得到一些信息:


  1. 公共且确定类属性codemessage
  2. 公共但类型不确定的属性result,可能是对象也可能是数组;
  3. 返回列表数据的报文时list对象中需要包含公共的属性size和pages;
  4. 返回列表数据中的单个元素和返回指定数据的对象都包含一个公共的id字段,可以抽取到公共父类中使用,因为数据库必须有数据唯一的标识;


通过UML类图来看一下没有泛型的结构

3.png


BaseResponse:

抽取接口公共属性:code,message,result

class BaseResponse {
  code: number;
  message: string;
  result: any;
  constructor(code = 200, message: string, result: any) {
    this.code = code;
    this.message = message;
    this.result = result;
  }
}

BaseData:

模拟数据库表数据的唯一主键id

class BaseData {
  id: number;
  constructor(id: number) {
    this.id = id;
  }
}

Person:

模拟数据库人员表单条数据

class Person extends BaseData {
  name: string;
  age: number;
  constructor(id: number, name: string, age: number) {
    super(id);
    this.name = name;
    this.age = age;
  }
}

ListPersonData:

模拟数据库人员表多条数据

class ListPersonData {
  size: number;
  pages: number;
  persons: Person[];
  constructor(size: number, pages: number, persons: Person[]) {
    this.size = size;
    this.pages = pages;
    this.persons = persons;
  }
}

ListPersonResponse:
class ListPresonResponse extends BaseResponse {
  // 组装数据
  static toResponse(): object {
    const person = new Person(100, "zhangsan", 18);
    const result = new ListPersonData(20, 1, [person]);
    const listDataResponse = new ListPresonResponse(
      200,
      "数据加载完成",
      result
    );
    return listDataResponse;
  }
}

PersonResponse:
class PersonResponse extends BaseResponse {
  // 组装数据
  static toResponse(): object {
    const person = new Person(100, "zhangsan", 18);
    const personResponse = new PersonResponse(200, "数据加载完成", person);
    return personResponse;
  }
}


无泛型结构说明:

4.png通过输出我们可以看到需求已经实现了,也可以看得出来类直接的关系比较紧密,不利于扩展和维护。我们看一看应用泛型后有什么变化吧。


对类进行升级-应用泛型:

5.png


1. 对BaseResponse升级支持泛型:
class BaseResponse<T> {
  code: number;
  message: string;
  result: T;
  constructor(code = 200, message: string, result: T) {
    this.code = code;
    this.message = message;
    this.result = result;
  }
}

2. 对报错的ListPresonResponse配置泛型类型:
class ListPresonResponse extends BaseResponse<ListPersonData> {
  // 组装数据
  static toResponse(): object {
    const person = new Person(100, "zhangsan", 18);
    const result = new ListPersonData(20, 1, [person]);
    const listDataResponse = new ListPresonResponse(
      200,
      "数据加载完成",
      result
    );
    return listDataResponse;
  }
}


  1. 配置泛型类型前的类型提示:(因为类型不确定只能是any)

6.png


  1. 配置泛型类型后的类型提示:

7.png


3. 对报错的PersonResponse配置泛型类型:
class PersonResponse extends BaseResponse<Person> {
  // 组装数据
  static toResponse(): object {
    const person = new Person(100, "zhangsan", 18);
    const personResponse = new PersonResponse(200, "数据加载完成", person);
    return personResponse;
  }
}


  1. 配置泛型类型前的类型类型提示:(因为类型不确定只能是any)

8.png


  1. 配置泛型类型后的类型类型提示:

9.png


4. 返回数据列表的ListPersonData类我们应用泛型后进行改造,抽取为统一的ListData类

切记ListData为公共类不显示的关联其他类,原来的persons属性改为list属性

class ListData<T extends BaseData> {
  size: number;
  pages: number;
  list: T[];
  constructor(size: number, pages: number, list: T[]) {
    this.size = size;
    this.pages = pages;
    this.list = list;
  }
}

5. 调整ListPresonResponse符合我们的泛型规定
class ListPresonResponse extends BaseResponse<ListData<Person>> {
  // 组装数据
  static toResponse(): object {
    const person = new Person(100, "zhangsan", 18);
    const result = new ListData(20, 1, [person]);
    const listDataResponse = new ListPresonResponse(
      200,
      "数据加载完成",
      result
    );
    return listDataResponse;
  }
}


应用泛型后说明:

应用泛型后的代码变得更容易扩展,我们如果新增一个商品表的话,对应的单条数据返回和多条数据返回的结构将可以很方便的在原来的基类上进行扩展了,如果需要在基类中进行属性的扩展和变更将受影响到所有子类中。 我们来看一下为商品对象报文增加的类:


class Goods extends BaseData {
  // 实现内部属性
}
class ListGoodsResponse extends BaseResponse<ListData<Goods>> {
  // 实现组装数据函数(模拟使用)
}
class GoodsResponse extends BaseResponse<Goods> {
  // 实现组装数据函数(模拟使用)
}


结语:


泛型的应用使我们的程序在设计过程中对结构进行抽象但不指明具体类的类型,使的基类变得有规矩的宽松,延时到进行子类的实现时再补充泛型类型进行明确


相关文章
|
4月前
|
安全 JavaScript 编译器
TypeScript 泛型:解锁灵活且安全的代码重用
TypeScript 泛型:解锁灵活且安全的代码重用
|
4月前
|
存储 JavaScript 安全
TypeScript 泛型:让你的代码既灵活又安全的“魔法”
TypeScript 泛型:让你的代码既灵活又安全的“魔法”
|
7月前
|
人工智能 JavaScript 程序员
一文彻底搞明白HarmonyOS基础TypeScript中的泛型函数
程序员Feri是一位拥有12年+经验的技术专家,擅长嵌入式、鸿蒙、人工智能和Java等领域。本文深入探讨TypeScript中的泛型函数,涵盖基础语法、类型约束、高级技巧及应用场景。通过泛型函数,实现代码逻辑与具体类型的解耦,提升类型安全性和复用性。内容包括集合操作、API抽象、工具类开发等实际应用,以及条件类型、默认类型参数和工具类型的高级技巧。最后提醒开发者注意过度泛型化和性能权衡问题,总结泛型函数在TypeScript类型系统中的核心地位及其未来发展方向。
185 1
一文彻底搞明白HarmonyOS基础TypeScript中的泛型函数
|
11月前
|
数据采集 JavaScript 前端开发
异步请求在TypeScript网络爬虫中的应用
异步请求在TypeScript网络爬虫中的应用
|
JavaScript 编译器
typescript之泛型
typescript之泛型
247 60
|
12月前
|
JavaScript 前端开发 安全
JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择
本文深入探讨了JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择。JavaScript以其灵活性和广泛的生态支持著称,而TypeScript通过引入静态类型系统,提高了代码的可靠性和可维护性,特别适合大型项目。文章还讨论了结合使用两种语言的优势,以及如何根据项目需求和技术背景做出最佳选择。
1313 4
|
12月前
|
机器学习/深度学习 人工智能 JavaScript
JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景
本文探讨了JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景。JavaScript将注重性能优化、跨平台开发、AI融合及WebAssembly整合;TypeScript则强调与框架整合、强类型检查、前端工程化及WebAssembly的深度结合。两者结合发展,特别是在Vue 3.0中完全采用TypeScript编写,预示着未来的Web开发将更加高效、可靠。
528 4
|
JavaScript 安全
typeScript进阶(14)_泛型和注意事项
TypeScript中的泛型允许创建可重用的代码。泛型可以定义函数、接口、类,支持传递类型参数,实现类型安全。泛型可以用于数组,约束类型参数必须符合特定的接口,也可以在接口和类中使用。泛型类可以包含多个类型参数,甚至在泛型约束中使用类型参数。
150 1
typeScript进阶(14)_泛型和注意事项
|
JavaScript 前端开发
TypeScript【类型别名、泛型】超简洁教程!再也不用看臭又长的TypeScript文档了!
【10月更文挑战第11天】TypeScript【类型别名、泛型】超简洁教程!再也不用看臭又长的TypeScript文档了!
|
JavaScript 前端开发 安全
TypeScript进阶:类型系统与高级类型的应用
【10月更文挑战第25天】TypeScript作为JavaScript的超集,其类型系统是其核心特性之一。本文通过代码示例介绍了TypeScript的基本数据类型、联合类型、交叉类型、泛型和条件类型等高级类型的应用。这些特性不仅提高了代码的可读性和可维护性,还帮助开发者构建更健壮的应用程序。
157 0