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

如何用TypeScript类型语法表达按需返回字段的Web API响应?

Representing Conditional API Responses in TypeScript

Great question! This is a super common scenario when working with APIs that let you pick and choose which fields to return, and TypeScript’s generic and mapped types are perfect for modeling this behavior. Here’s a step-by-step solution:

First, let’s split your API data into two distinct parts: fields that are always present no matter what, and fields that are optional (only returned if explicitly requested).

Step 1: Define Base Types

Start by creating types for both categories of fields:

// Fields that require explicit request to be included in the response
type OptionalApiFields = {
  a: string;
  b: string;
  c: string;
};

// Fields that are always included in every API response
type MandatoryApiFields = {
  d: string;
};

Step 2: Build a Generic Response Type

Next, we’ll create a generic type that combines the requested optional fields with the mandatory ones. We use Pick to select only the requested fields from OptionalApiFields, then intersect that with the mandatory fields to ensure they’re always present:

// Generic type that adapts based on which optional fields you request
type ApiResponse<T extends keyof OptionalApiFields = never> = 
  Pick<OptionalApiFields, T> & MandatoryApiFields;

The = never default means if you don’t request any optional fields, the response will only include the mandatory d field.

Step 3: Type the API Function

Now we can type your getResponse function to infer the requested fields and return the correct response type automatically:

// Mock implementation of your API call (adjust for real use)
function getResponse<T extends keyof OptionalApiFields>(
  fields: T[]
): ApiResponse<T> {
  // Full dataset the API has available
  const fullData = {
    a: "hello",
    b: "world",
    c: "of goo",
    d: "i am always present"
  };

  // Start with mandatory fields, then add requested optional ones
  const filteredResponse = { d: fullData.d } as ApiResponse<T>;
  fields.forEach(field => {
    filteredResponse[field] = fullData[field];
  });

  return filteredResponse;
}

Step 4: See It in Action

Let’s test this to confirm the type safety works as expected:

// Request fields "a" and "b"
const response1 = getResponse(["a", "b"]);
// Type: { a: string; b: string; d: string }
console.log(response1.a); // "hello"
console.log(response1.b); // "world"
console.log(response1.d); // "i am always present"
// @ts-expect-error: Property 'c' doesn't exist here (we didn't request it!)
console.log(response1.c);

// Request no optional fields
const response2 = getResponse([]);
// Type: { d: string }
console.log(response2.d); // "i am always present"
// @ts-expect-error: "a" isn't included here
console.log(response2.a);

Bonus: Flexible Input

If you want to support passing a single field instead of an array (e.g., getResponse("a")), adjust the function signature slightly:

function getResponse<T extends keyof OptionalApiFields>(
  fields: T | T[] = []
): ApiResponse<T> {
  const fieldList = Array.isArray(fields) ? fields : [fields];
  // Rest of the implementation stays the same
}

This setup gives you full type safety—TypeScript will autocompletable fields based on your request, and flag any attempts to access fields you didn’t ask for.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:35:27