Skip to main content

TypeScript

Keq 提供了完善的 TypeScript 支持,让你在编写代码时获得完整的类型提示和类型安全保障。

指定响应类型

Keq 支持通过泛型参数指定响应类型:

import { request } from "keq"

interface Cat {
  id: string
  breed: string
  name: string
}

// 使用泛型参数指定返回类型
const cat = await request.get<Cat>("/api/cats/123")
// cat 的类型为 Cat

const cats = await request.get<Cat[]>("/api/cats")
// cats 的类型为 Cat[]

API 类型约束

使用 KeqApiSchema 接口

当你需要为特定的 API 定义类型时,可以扩展 KeqApiSchema 接口:

import { KeqRequest, KeqApiSchema, KeqQueryValue, KeqParamValue } from "keq"

// 定义 API 的类型结构
export interface CatApiSchema extends KeqApiSchema {
  "/cats": {
    get: {
      requestParams: {
        [key: string]: KeqParamValue // 必须包含索引签名
      }
      requestQuery: {
        breed: string
        [key: string]: KeqQueryValue // 必须包含索引签名
      }
      requestHeaders: {
        Authorization: string
        [key: string]: string | number // 必须包含索引签名
      }
      requestBody: {}
      responseBody: {
        id: string
        breed: string
        name: string
      }[]
    }
    post: {
      requestParams: {
        [key: string]: KeqParamValue
      }
      requestQuery: {
        [key: string]: KeqQueryValue
      }
      requestHeaders: {
        Authorization: string
        [key: string]: string | number
      }
      requestBody: {
        breed: string
        name: string
      }
      responseBody: {
        id: string
        breed: string
        name: string
      }
    }
  }
  "/cats/{id}": {
    get: {
      requestParams: {
        id: string
        [key: string]: KeqParamValue
      }
      requestQuery: {
        [key: string]: KeqQueryValue
      }
      requestHeaders: {
        [key: string]: string | number
      }
      requestBody: {}
      responseBody: {
        id: string
        breed: string
        name: string
      }
    }
  }
}

// 创建带类型的请求实例
const catAPI = new KeqRequest<CatApiSchema>()

// 现在你会获得完整的类型提示和检查
const cats = await catAPI
  .get("/cats")
  .query("breed", "Persian") // ✅ 正确:breed 是 string 类型
  .query("breed", 123)       // ❌ 错误:TypeScript 会提示类型不匹配
  .set("Authorization", "Bearer token")

const cat = await catAPI
  .get("/cats/{id}")
  .param("id", "123") // ✅ 正确:id 是 string 类型

扩展自定义选项

通过模块扩展,你可以为 Keq 添加自定义选项并获得类型支持:

import { Keq, KeqMiddleware } from "keq"

// 扩展 KeqOptions 接口
declare module "keq" {
  interface KeqOptions<T> {
    silent(value: boolean): Keq<T>
  }
}

// 实现对应的中间件
function errorHandlerMiddleware(): KeqMiddleware {
  return async (context, next) => {
    await next()

    if (context.response && context.response.status >= 400) {
      const isSilent = context.options.silent || false
      if (!isSilent) {
        console.error(`Request failed: ${context.response.status}`)
      }
    }
  }
}

// 现在可以使用自定义选项,并有类型提示
await request
  .get("/api/data")
  .option("silent", true)  // ✅ 有类型提示