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

TypeScript中如何从已知类型对象提取泛型指定属性?

TypeScript从已知对象提取泛型指定属性的实现方案

核心问题说明

TypeScript泛型是编译时特性,编译后会被完全擦除,因此无法直接通过泛型类型在运行时获取要提取的属性列表。必须结合运行时传入的属性名数组,同时通过泛型约束确保属性的合法性。

修正后的完整实现代码

interface IPerson {
  name: string;
  age: number;
  height: number;
  weight: number;
  job: string;
}

interface IAgeAndJob {
  age: number;
  job: string;
}

// 修正IHeightAndWeight的weight类型,与IPerson保持类型兼容
interface IHeightAndWeight {
  height: number;
  weight: number;
}

const person: IPerson = {
  name: 'Leon Kennedy',
  age: 21,
  height: 5.11,
  weight: 165,
  job: 'Police Officer'
};

/**
 * 从对象中提取指定属性
 * @param obj 源对象
 * @param keys 需要提取的属性名数组
 * @returns 包含指定属性的新对象
 */
const mapProperties = <TObj, TKeys extends keyof TObj>(obj: TObj, keys: TKeys[]): Pick<TObj, TKeys> => {
  const result = {} as Pick<TObj, TKeys>;
  keys.forEach(key => {
    result[key] = obj[key];
  });
  return result;
};

// 使用示例1:自动推断返回类型
const ageAndJob = mapProperties(person, ['age', 'job']);
// ageAndJob类型为 Pick<IPerson, 'age' | 'job'>,与IAgeAndJob结构完全一致

// 使用示例2:断言为指定接口(需严格匹配时)
const ageAndJob2 = mapProperties(person, ['age', 'job']) as IAgeAndJob;

// 使用示例3:提取height和weight属性
const heightAndWeight = mapProperties(person, ['height', 'weight']) as IHeightAndWeight;

关键细节解释

  1. 泛型约束:TKeys extends keyof TObj确保传入的属性名一定是源对象的有效键,避免出现不存在的属性报错。
  2. 运行时逻辑:必须传入属性名数组keys,因为编译后泛型信息消失,只能通过这个数组明确要提取的属性。
  3. 返回类型:Pick<TObj, TKeys>是TypeScript内置工具类型,自动生成包含指定属性的对象类型,无需手动重复定义接口。

原写法的问题分析

  • 泛型参数<IPerson, T>写法错误:第一个参数应为通用类型参数,而非具体接口名;
  • 仅通过as T做类型断言,但实际返回空对象,没有真实的属性提取逻辑;
  • 缺少运行时属性列表,无法确定要提取哪些属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:32:47