TypeScript搭配项目axios request接口做推倒

1,852 阅读3分钟

简述

随着前端技术的发展,TypeScript 已经逐渐取代Javascript,尤其在各大开源项目,或者是其他开源js项目,我们都可以看到ts的身影,例如我们熟知的vue3 就是用ts重构的;

  • 在使用ts的时候,最大的一个好处就是可以给js各种类型约束,使得Js能够完成静态代码分析,推断代码中存在的类型错误或者类型提示,不需要在运行时候才发现错误;
  • TS完成类型推导,需要事先知道变量的类型,所以我们得需要事先给变量定义好明确的类型,这可以让TS很好的完成类型推倒;

首先我们需要简单了解一下ts:
什么是TypeScript

在这篇中学会ts的一些泛型,文件声明,接口(interface),type,一系列类型描述即可;
个人觉得 学会ts的最快方式就是看一些开源代码; 可以了解到很懂泛型的使用;
本篇文章只是浅度的使用到泛型;

正文

封装一个axios,或者 request 请求函数;

通常我们封装函数的格式

// request.js

/**
 * @description: 请求函数
 * @param {string} path 路径
 * @param {object} params 携带参数
 * @returns {object}
 */
export default async function request(path, params) {
    // ...
}

页面中使用的情况大概如下;

const [d, setData] = useState({}); 
// 这是一个List接口 我们需要使用上面的request方法
async function getList() {
    const res = await request('v1/app/list', {search: 1});
    if(res.code === 200) {
        setData(res.data)
    }
    
}

可以看到我们上面封装函数一般都是 path params请求路径; 返回的是一个promise resolve结果; 结构一般是:

{
 code: 200,
 data: {},
 errMsg: '错误提示'
}

ts接口书写

ok 有了以上的信息,我们来简单做一下函数的封装;

首先我们先写一下 返回格式的描述;

// 服务端接口基本类型
type Server<T> = {
    errMsg: string;
    data: T;
    code: 200 | 1000 | 1001 | 404 | 500 ...;
};

学习完.d.ts, 以及interface后,我们知道interface 声明的接口会自动合并,而.d.ts中声明的可以在全局中任何地方去使用;

所以可以在.d.ts 中是声明我们所需要的接口名字,我们暂把它定死为API;

因为我们需要根据path 自动推导出来params参数,data等; 所以需要定义一种有关联意义的;

// abc.d.ts
interface API {
    '/v1/app/list': {
        params: {
            /** 我是a参数 */
            a: number;
            /** 我是b参数 */
            b: string;
        },
        data: {
            /** 数字类型的数组 */
            list: number[];
        }
    }
    '/v1/app/home': {
        params: {},
        data: {}
    }
}


interface API {
    '/v1/app/abc': {
        params: {},
        data: {}
    }
}

我们可以这样的去写, interface的结构; 可以看到 list home abc 三个接口都有自己的关联的params 与 data;

函数的写法

接下来看函数的描述

// 请求方法参数约束
function Drequest<URL extends keyof API>(
	path: URL,
	params: API[URL]['params'],
	method?: 'POST'
): Promise<Server<API[URL]['data']>>

export default const request:typeof Drequest = (path, params, method = 'POST') => {
   
}

在上面有.d.ts中有相对应的 API接口了,可以使用推导; 这个函数是最后关键的组装;
keyof 是把 interface 的key变成联合类型

'/v1/app/list' | '/v1/app/home' | '/v1/app/abc' 

extends 是看URL 是否可以是联合类型中的一种
看到最上面封装的函数有 path params ,这样子我们就可以与 path 一一对应起来了;

看一下页面使用情况吧:

image.png

image.png

image.png

总结

经过上面这些ts 接口的封装可以自动校验 params 的参数类型,以及推导data字段类型; 不过这些 都需要自己去写接口字段data 以及用 /** */ 做注释;
这样做会加占用前期的开发时间,不过对于之后的维护还是很有利的; 与服务端定好的字段更能严格一点,我们也会参考提供的api接口文档,来书写ts的结构 与 类型;