Skip to content

如何使用泛型写一个自动提示api方法及参数的功能

场景一

ts
$http.get(API_URL.xx, obj)
$http.post(API_URL.xx, obj)

维护了 url 枚举

没有维护 接口 入参出参

只关联入参 和 出参

ts
// 数据-接口名常量枚举
const API = {
  getList: 'api/getList',
  postList: 'api/postList'
} as const

type ApiType = typeof API[keyof typeof API]

// 类型-接口对应的请求参数/响应参数
interface ApiReqRespType {
  'api/getList': {
    requestData: { id: string },
    respontData: { list: string[], total: number }
  }
  'api/postList': {
    requestData: { id: string, list: string[] },
    respontData: { success: boolean }
  }
}

// 类型-接口返回数据结构
interface ResultData {
  data: string
}

// 类型-接口返回数据结构
interface RespontData<T> {
  msgCode: number;
  errorMsg: string;
  data: T
}

const request = <T extends ApiType>(url: ApiType, params:ApiReqRespType[T]['requestData']): Promise<RespontData<ApiReqRespType[T]['respontData']>> => {
  return new Promise(( resolve ) => {
    if(url === 'api/getList') {
      resolve({msgCode:200,errorMsg:'',data:{list:['1'],total:1}})
    }else if(url === 'api/postList')  {
      resolve({msgCode:200,errorMsg:'',data:{success:true}})
    }
  })
}

// url 用常量枚举不需要 ts 推导
request<typeof API.getList>(API.getList, 1).then(( res ) => console.log(res.data))

// vue3 的 ref 怎么实现不用泛型也能推断类型

makeType

场景二

umi 配置 入参、出参、基础配置(mockUrl、devUrl、prodUrl)

维护了泛型表达式