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

TypeScript中如何将JSON正确映射到指定Interface?

How to Cleanly Extract Specific Fields from API Responses in TypeScript

Great question! Let's break this down first—why your type assertion isn't working, then look at cleaner alternatives to get exactly the fields you need.

Why Type Assertions Don't Strip Extra Properties

First off, the reason response.data.map((p: any) => p as IProject); doesn't remove url, startDate, or other extra properties is because TypeScript is a compile-time only type system. Type assertions don't modify the actual runtime object—they just tell the compiler "trust me, this value matches this type". So those extra fields stick around at runtime, even though TypeScript treats the object as an IProject.

Better Solutions

Option 1: Destructuring Assignment (Cleanest for One-Off Use)

This is a more concise take on your manual mapping, using object destructuring to pull out exactly the fields you need, then returning a new object with only those fields:

response.data.map(({ id, name, description }) => ({ id, name, description }));

This is readable, straightforward, and avoids repeating p. for every field. If your interface uses a different casing (like Id instead of the server's id), you can rename fields during destructuring:

// Match your IProject interface's Id property
response.data.map(({ id: Id, name, description }) => ({ Id, name, description }));

Option 2: Reusable pick Function (Best for Multiple Uses)

If you need to extract specific fields from objects in multiple places, create a generic pick function that leverages TypeScript's built-in Pick utility type for full type safety:

function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
  const picked = {} as Pick<T, K>;
  keys.forEach(key => {
    picked[key] = obj[key];
  });
  return picked;
}

// Usage with your project data
response.data.map(project => pick(project, 'id', 'name', 'description'));

This function is type-safe: TypeScript will enforce that the keys you pass actually exist on the input object, and the returned type will only include those keys (perfect for matching your IProject interface).

Option 3: Dynamic Field Filter (Less Type-Safe, But Flexible)

If you have a dynamic list of allowed fields (e.g., loaded from config), you can use Object.entries and Object.fromEntries—though note this requires a type assertion since TypeScript can't infer the exact type automatically:

const allowedFields = ['id', 'name', 'description'] as const;
response.data.map(project => 
  Object.fromEntries(
    Object.entries(project).filter(([key]) => allowedFields.includes(key as typeof allowedFields[0]))
  ) as IProject
);

Use this only when you need runtime flexibility; it's less type-safe than the first two options.

Final Recommendation

  • For a single use case, go with destructuring assignment—it's the most readable and concise.
  • If you need to reuse this logic across your codebase, the generic pick function is ideal for type safety and reusability.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:22:22