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);
    });
};

参考

官网:泛型

 

posted @ 2021-12-29 16:25  坤嬷嬷  阅读(91)  评论(0编辑  收藏  举报