javascript - Typescript : 创建自定义类型 axios 实例
问题描述
我想用 axios 实例创建一个复杂的类型名称 api,这样我就可以像这样使用基本实例:
api.get("url")...
而且还能够拥有新的动态物体,例如:
api.myApi.get("url")
最后,能够像这样读取实例列表:
api.list
必须退货
我的 API
当我想扩展 AxiosInstance 或向主实例注入属性时,总是会收到类型错误。任何想法?
我的测试:
type apiInstances = Record<string, AxiosInstance>
type apiList = Record<'list', string[]>
let api: apiInstances | apiList
const instance = (baseURL: string) =>
axios.create({
baseURL
})
const instances = { instance('myApi') }
api = { ...instances, ...instance(''), list }
我写的时候出错api.myApi.get("...")
'apiInstances | 类型不存在属性'myApi' apiList'
解决方案
我觉得你走的很好。您可以做的最好的事情是抽象 axios 客户端,就像您对另一个 http 客户端所做的那样,并隐藏 axios 实现。为此,您可以为
export class HttpClient extends HttpMethods {
_http: AxiosInstance;
constructor() {
super();
this._http = axios.create({
...this._options,
validateStatus: status => status >= 200 && status < 400,
});
}
setAdditionnalHeaders(headers: object, override?: boolean): void {
this._options = _.merge({}, override ? {} : this._options, { headers });
}
public async get<T>(path: string, params?: any, headers?: object): Promise<Result<T>> {
if (headers) {
this.setAdditionnalHeaders(headers, true);
}
const result = await this._http({
method: 'GET',
url: path,
params,
headers: this._options,
...this.hydrateConfig(this._config),
});
return result;
}
}
export abstract class HttpMethods {
public _http: any;
protected _options: object;
public abstract get<T>(path: string, params?: any, headers?: object): Promise<Result<T>>;
}
然后使用可链接的函数,您将在其中注入隐藏 axios 在其中使用的类。
export function httpBuilder<I extends HttpMethods>(client: I): IHttpBuilder {
return {
...httpRequestMethods(client),
};
}
function httpRequestMethods(instance: HttpMethods): BuilderMethod {
const { config } = instance;
return {
get<T>(path: string, params?: any, headers?: object): ChainableHttp & HttpExecutableCommand<T> {
return {
...executableCommand<T>(path, instance, 'GET', requests, null, params, headers),
};
},
}
function executableCommand<T>(
path: string,
instance: HttpMethods,
commandType: CommandType,
requests: RequestType[],
data?: any,
params?: any,
headers?: object,
): HttpExecutableCommand<T> {
return {
async execute(): Promise<Result<T>> {
const result = await getResolvedResponse<T>(path, instance, commandType, data, params, headers);
return result;
},
};
}
async function getResolvedResponse<T>(
path: string,
instance: HttpMethods,
commandType: CommandType,
data?: any,
params?: any,
headers?: object,
): Promise<Result<T>> {
let result: Result<T>;
if (commandType === 'GET') {
result = await instance.get<T>(path, params, headers);
}
return result;
}
如果您想在您的 http 客户端上执行额外的功能,无论是 axios、fetch 还是您想要的任何东西,这是一个帮助示例:-)
推荐阅读
- python - python datetime function for different type of timezone
- ios - NavigationBar 在动画期间改变他的颜色
- ios - Visual Studio Mac 2019 - Xamarin.Forms 不会连接到调试器
- reactjs - React / Gatsby - 相同的 useEffect 代码在不同的组件中不起作用
- javascript - Check if string is in an array of objects VueJS?
- jquery - 赛普拉斯 - 反转每个
- python - 以列表为参数的迭代不考虑每个字符
- r - How to simplify spatial polygon using rmapshaper?
- r - R中的简单条件格式
- php - 从现有文件夹中选择随机图像