You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript中基于请求字段实现API响应类型安全?

实现API响应的类型安全方案

原生JavaScript本身不具备静态类型检查能力,要实现类型安全,最直接的方案是使用TypeScript;如果暂时不想迁移到TS,也可以通过JSDoc在编辑器中获得类型提示。以下是两种场景的具体实现:

一、TypeScript 实现方案

1. 定义字段映射与核心类型

先把数字标识和字段名的映射用枚举定义,再创建工具类型,根据传入的字段数组动态生成返回类型:

// 定义数字标识对应字段名的枚举
enum FieldId {
  FirstName = 1,
  LastName = 2,
  Age = 3,
  Address = 4,
  Email = 5
}

// 定义所有字段的完整类型
type UserFullFields = {
  firstname: string | null;
  lastname: string | null;
  age: number | null;
  address: string | null;
  email: string | null;
};

// 工具类型:根据传入的字段ID数组,提取对应的返回类型
type PickUserFields<T extends FieldId[]> = {
  [K in keyof UserFullFields as T[number] extends FieldId[K] ? K : never]: UserFullFields[K];
};

2. 改造请求函数,添加类型约束

让server函数接收指定的FieldId数组,并返回对应的动态类型:

function server<T extends FieldId[]>(fields: T): PickUserFields<T> {
  const allFields: Record<FieldId, keyof UserFullFields> = {
    [FieldId.FirstName]: 'firstname',
    [FieldId.LastName]: 'lastname',
    [FieldId.Age]: 'age',
    [FieldId.Address]: 'address',
    [FieldId.Email]: 'email'
  };

  const result = {} as PickUserFields<T>;

  fields.forEach(field => {
    if (allFields[field]) {
      result[allFields[field]] = null;
    }
  });

  return result;
}

// 使用示例:
const response = server([FieldId.FirstName, FieldId.Age]);
// 此时response的类型为 { firstname: string | null; age: number | null },编辑器会自动做类型检查和提示

二、JavaScript 结合 JSDoc 实现类型提示

如果项目暂时无法迁移到TypeScript,可以用JSDoc注释为函数添加类型约束,在VSCode等编辑器中获得类型提示:

/**
 * @typedef {Object} UserFullFields
 * @property {string|null} firstname
 * @property {string|null} lastname
 * @property {number|null} age
 * @property {string|null} address
 * @property {string|null} email
 */

/**
 * @typedef {1|2|3|4|5} FieldId
 */

/**
 * @template {FieldId[]} T
 * @param {T} fields
 * @returns {Pick<UserFullFields, T[number] extends 1 ? 'firstname' : T[number] extends 2 ? 'lastname' : T[number] extends 3 ? 'age' : T[number] extends 4 ? 'address' : 'email'>}
 */
function server(fields) {
  const allFields = {
    1: 'firstname',
    2: 'lastname',
    3: 'age',
    4: 'address',
    5: 'email'
  };

  const result = {};

  fields.forEach(field => {
    if (allFields[field]) {
      result[allFields[field]] = null;
    }
  });

  return result;
}

// 使用示例:
const response = server([1, 3]);
// 编辑器会提示response包含firstname和age字段,具备类型提示能力

内容的提问来源于stack exchange,提问作者Jon You

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 10:52:46