TypeScript学习(十二)泛型
总结
泛型就是广泛的类型(任意类型),泛型变量T,可以是其他的名字,例如U、M等,仅代表类型
例如泛型函数,可以在调用的时候传入泛型参数决定类型,相比any会有更精确的含义表达
可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。泛型可以帮助我们避免重复代码以及对不特定数据类型的支持(类型校验) 比如说这样,我们写一个函数,然后传入参数,要求返回参数,这样的话,按照ts的写法
function get1(val:string):string{
return val
}
function get2(val:number):number{
return val
}
//这样就很麻烦,但是我们可以用any
function get3(val:any):any{
return val
}
//但是any的话,就相当于放弃了类型检验,然而泛型支持不特定的数据类型
function get4<T>(val:T):T{
return val
}
实战
// 例1
// 节流
// 类型不确定
export function throttle<T extends any[]>(
// 类型不确定
this: any,
fn: (...arg: T) => void,
delay: number
): (...arg: T) => void {
let timer: number | null = null;
const that = this;
return (...args: T): void => {
if (!timer) {
timer = setTimeout(() => {
fn.apply(that, args);
timer = null;
}, delay);
}
};
}
// 例2
export type IResponse<T> = {
code: number;
message: string;
data: T;
};
export const request = async <T>(options: IRequest): Promise<IResponse<T>> => {
const { header: originHeader = {}, url: _url, method = 'POST' } = options;
const hasHost = _url.startsWith('http');
let httpHost = defaultConfig.host;
if(options.origin && host[options.origin]) { // 如果设置了自定义域名,则使用这个
httpHost = host[options.origin];
}
const url = hasHost ? _url : httpHost + _url;
return new Promise((resolve, reject) => {
const originData = options.data;
options.data = {
...originData,
eOpenId: Cookie.get('eOpenId'),
};
const requestParam: any = {
...options,
url: url,
method,
header: {
...defaultConfig.header,
...originHeader,
// #ifdef MP-WEIXIN
cookie: Cookie.toCookieString(),
// #endif
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// 类型不确定
success: (wrapRes: any) => {
console.log("接口请求",url);
console.log("request resp:",wrapRes);
if (wrapRes.errMsg !== 'request:ok') {
debug.error('服务器异常');
reportMonitor('0', 1); // 服务器异常
reject({
code: wrapRes.statusCode,
message: wrapRes.errMsg,
});
return;
}
let ret = wrapRes.data as IResponse<T>;
debug.info('[request]', options.url, originData, ret.data);
if (typeof ret !== 'object') {
ret = {
data: ret as any,
} as IResponse<T>;
}
const tempRes: any = ret;
ret.data = ret.data || {...tempRes};
// eslint-disable-next-line no-undefined
ret.code = ret.code !== undefined ? ret.code : wrapRes.statusCode;
// #ifdef MP-WEIXIN
if (ret.code === 500 && ret.message === '用户身份校验失败') {
rediretcToLogin('/pages/index/index', {}, true);
reject(ret);
return;
}
// #endif
if (ret.code > 0 && ret.code < 1000 && ret.code !== 200) {
debug.error('接口业务异常:', options.url, originData, ret);
reportMonitor('1', 1); // 接口业务异常
reject(ret);
return;
}
resolve(ret);
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// 类型不确定
fail: (e: any) => {
reject(e);
},
};
if(options.origin !== 'GAMECLOUND_HOST') {
requestParam.withCredentials = true;
}
uni.request(requestParam);
});
};
参考