Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

希望能够为 wx.request 增加出入的泛型 #6

Open
Locter9001 opened this issue May 14, 2024 · 4 comments
Open

希望能够为 wx.request 增加出入的泛型 #6

Locter9001 opened this issue May 14, 2024 · 4 comments

Comments

@Locter9001
Copy link

直接上代码,这样可以在请求中就获得良好的代码提示,不用再搞一个变量使用 as 去做转换

interface RequestParams {
  a: number
  b: string
}

interface ResponseData {
  code: number
  msg: string
}

wx.request<ResponseData, RequestParams>({
  url: 'https://www.baidu.com',
  success(res) {
    expectType<string>(res.errMsg)
    expectType<WechatMiniprogram.RequestSuccessCallbackResult>(res)
  },
})

我个人一直都是这么做的,也用了一段时间,体验非常好,但是每次都得手动改一下声明文件

@xiaweiss
Copy link
Owner

收到,有阵子没更新了。微信 api 每次更新,机器生成的代码顺序变动都很大,不太容易跟踪。后面有空我会考虑开发 2.0,重新手动实现下,也能处理 组件 props 无法指定类型的问题。

@Locter9001
Copy link
Author

好的,我还想提交个pr呢,原来是机器生成的,那好吧,等您

@xiaweiss
Copy link
Owner

欢迎提交 pr,目前只要能向前兼容就好

@xiaweiss
Copy link
Owner

xiaweiss commented May 14, 2024

我自己也遇到过这个问题,是自己封装 request 方法解决的。顺便 request 方法里,可以处理一些公共逻辑,例如登录态需要的 token 等。

举个例子:

import { request } from '../utils/index'

interface NoteCommentTransData {
  /** 评论 uuid */
  commUuid: string
  /** 文件 uuid */
  fileUuid: string
}

interface NoteCommentTransResponse {
  /** 识别文本 */
  text: string
}

/**
 * 评论 - 笔记评论点赞
 */
export const NoteCommentTrans = (data: NoteCommentTransData) => {
  return request<NoteCommentTransResponse>({
    method: 'post',
    url: '/note/wxa/v1/note/comment/trans',
    data
  }).then(res => res.data)
}

request.ts

/**
 * 接口请求参数
 * @see https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html
 */
interface ReqeustConfig {
  /** HTTP 请求方法 */
  method: 'GET' | 'POST' | 'get' | 'post',
  /** 基础路径 */
  baseURL?:
    'account' | 'https://dev-account.mowen.cn/api' |
    'note' | 'https://dev-note.mowen.cn/api' |
    'misc' | 'https://dev-misc.mowen.cn/api' |
    'user' | 'https://dev-user.mowen.cn/api' |
    'trade'| 'https://dev-trade.mowen.cn/api' |
    'https://asr.cloud.tencent.com/'
  /** 开发者服务器接口地址 */
  url: string
  /** 设置请求的 header,header 中不能设置 Referer。content-type 默认为 application/json */
  header?: object
  /** 请求的参数 */
  data?: string | object | ArrayBuffer,
  /** 超时时间,单位为毫秒。默认值为 10000 */
  timeout?: number
  /** 响应数据类型 */
  responseType?: 'text' | 'arraybuffer'
  /** 请求的错误提示,传 null 表示不提示 */
  requestErrorTip?: null
}

interface RequestResponse<T> {
  /** 开发者服务器返回的 cookies,格式为字符串数组 */
  cookies: string[]
  /** 开发者服务器返回的 HTTP Response Header */
  header: Record<string, string | number | boolean>
  /** 开发者服务器返回的 HTTP 状态码 */
  statusCode: number
  /** 开发者服务器返回的数据 */
  data: T
  /** 网络请求过程中一些调试信息,[查看详细说明](https://developers.weixin.qq.com/miniprogram/dev/framework/performance/network.html) */
  profile: WechatMiniprogram.RequestProfile
  /** 错误信息 */
  errMsg: string
  /** 没有网络时,只返回 errno、errMsg */
  errno?: number
}

/**
 * 请求接口方法
 */
export const request = <T = any, R = RequestResponse<T>>(export const request = <T = any, R = RequestResponse<T>>(
  {
    baseURL = 'https://www.example.com/api',
    url,
    data,
    header,
    timeout = 10000,
    method = 'get',
    responseType = 'text',
  } : ReqeustConfig
) : Promise<R> => {
  return new Promise((resolve, reject) => {
      // url + baseURL,同时判断下测试链接还是线上链接
      url = urlToRelease(baseURL, true, app) + url
      wx.request({
      method: method.toUpperCase() as Uppercase<ReqeustConfig['method']>,
      header: {
        'login-token': app.globalData.loginToken,
        ...header
      },
      url,
      data,
      timeout,
      responseType,
      success (res) {
        // vconsole 里缺少 netro打印出请求记录,方便调试
        console.log('request', url.split('api')[1], {url, req: data, res: res.data})

        if (res.statusCode === 200) {
          // fix: 序列化问题(旧版本 mac 2.18.1),传入特殊字符后,小程序可能出 bug,返回的 string 并且丢失转义符号,导致 json 序列化出错
          if (isMac() && responseType === 'text' && typeof res.data === 'string') {
            res.data = JSON.parse(res.data.split('\n').join('\\n'))
          }

          resolve(res as R)
        } else {
          const resData = res.data as RequestErrorData

          // 登录失败
          if (url === 'https://www.example.com/api/login') {
            log.error('request_signin', getCurrentPages().pop()?.route, res)
          }

          if (_requestErrorTip !== null) {
            requestErrorTip(resData, url)
          }

          // 报登录错误时,重新登录
          reLogin(resData)

          reject(res)
        }
      },
      async fail (err) {
        console.log('request', url.split('api')[1], {url, req: data, res: err})

        // 登录失败
        if (url === 'https://www.example.com/api/login') {
          log.error('request_signin', getCurrentPages().pop()?.route, err)
        }

        const [res] = await wxToPromise(wx.getNetworkType)

        // 网络断开
        if (res?.networkType === 'none') {
          wx.showToast({
            icon: 'none',
            title: '当前网络不可用,请稍后再试'
          })

        // 弱网
        } else if (app.globalData.isWeakNet) {
          wx.showToast({
            icon: 'none',
            title: '当前网络信号差,请稍后再试'
          })

        // 网络超时等
        } else {
          // 统一处理业务接口返回的错误码,toast 弹出中文
          wxErrTip(err)
        }
        reject(err)
      }
    })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants