编写泛型的关键目的是在成员之间提供有意义的约束,这些成员可以是:

  • 类的实例成员
  • 类的方法
  • 函数参数
  • 函数返回值

泛型常用 ​T​​U​​V​ 表示。


举例子:

​reverse​ 函数


​function reverse<T>(items: T[]): T[] {​

​const​​​ ​​toreturn = [];​

​for​​​ ​​(let i = items.length - ​​​​1​​​​; i >= ​​​​0​​​​; i--) {​

​toreturn.push(items[i]);​

​}​

​return​​​ ​​toreturn;​

​}​


​const​​​ ​​sample = [​​​​1​​​​, ​​​​2​​​​, ​​​​3​​​​];​

​let reversed = reverse(sample);​


​reversed[​​​​0​​​​] = ​​​​'1'​​​​; ​​​​// Error​

​reversed = [​​​​'1'​​​​, ​​​​'2'​​​​]; ​​​​// Error​


​reversed[​​​​0​​​​] = ​​​​1​​​​; ​​​​// ok​

​reversed = [​​​​1​​​​, ​​​​2​​​​]; ​​​​// ok​


温馨提示,当我们使用泛型的时候,应该想清楚,要使用泛型,是想约束什么。当我们搞不清的时候,那很有可能会误使用。直接使用any更佳

加载 json 返回值函数


​const​​​ ​​getJSON = <T>(config: { url: string; headers?: { [key: string]: string } }): Promise<T> => {​

​const​​​ ​​fetchConfig = {​

​method: ​​​​'GET'​​​​,​

​Accept: ​​​​'application/json'​​​​,​

​'Content-Type'​​​​: ​​​​'application/json'​​​​,​

​...(config.headers || {})​

​};​

​return​​​ ​​fetch(config.url, fetchConfig).then<T>(response => response.json());​

​};​


通常情况下,我们会把后端返回数据格式单独放入一个 interface 里:


​// 请求接口数据​

​export ​​​​interface​​​ ​​ResponseData<T = any> {​

​/**​

​* 状态码​

​* @type { number }​

​*/​

​code: number;​


​/**​

​* 数据​

​* @type { T }​

​*/​

​result: T;​


​/**​

​* 消息​

​* @type { string }​

​*/​

​message: string;​

​}​


把 API 单独抽离成单个模块时:


​// 在 axios.ts 文件中对 axios 进行了处理,例如添加通用配置、拦截器等​

​import​​​ ​​Ax from ​​​​'./axios'​​​​;​


​import​​​ ​​{ ResponseData } from ​​​​'./interface.ts'​​​​;​


​export function getUser<T>() {​

​return​​​ ​​Ax.get<ResponseData<T>>(​​​​'/somepath'​​​​)​

​.then(res => res.data)​

​.​​​​catch​​​​(err => console.error(err));​

​}​