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

如何通过键名从主/子对象获取属性?TypeScript类型问题

问题分析与解决方案

核心问题在于原函数的泛型约束错误,且未保证传入的key同时存在于主对象和coAuthors子对象中,导致TypeScript无法确认key能安全索引子对象。

第一步:优化接口定义(可选但更合理)

原接口中coAuthors的元组写法不符合实际场景,改成数组并复用Author属性定义,避免重复代码:

interface Author {
  id?: number;
  firstName?: string;
  lastname?: string;
  age?: number;
  // 子作者无需coAuthors属性,且所有字段必填
  coAuthors?: Array<Required<Omit<Author, 'coAuthors'>>>;
}

第二步:重构getByKeyName函数

调整泛型约束,确保key同时属于主对象和子对象的键,修正类型判断逻辑:

const getByKeyName = <T extends { coAuthors?: Array<U> }, U, K extends keyof T & keyof U>(
  item: T,
  key: K
) => {
  // 优先取主对象的属性值
  const mainValue = item[key];
  if (mainValue !== undefined) {
    return mainValue;
  }

  // 检查子作者数组是否有效
  if (item.coAuthors?.length) {
    return item.coAuthors[0][key];
  }

  // 兜底返回0(若需灵活兜底值,可新增参数)
  return 0 as T[K] | U[K];
};

调用示例

const author: Author = {
  id: undefined,
  coAuthors: [{ id: 101, firstName: "Jane", lastname: "Doe", age: 30 }]
};

const authorId = getByKeyName(author, 'id'); // 类型为number | undefined,值为101
const authorName = getByKeyName(author, 'firstName'); // 类型为string | undefined,值为"Jane"

关键优化点

  1. 精准泛型约束:通过K extends keyof T & keyof U确保key在主对象和子对象中都存在,彻底解决索引错误。
  2. 类型复用:用Required<Omit<Author, 'coAuthors'>>定义子作者类型,既避免重复编码,又保证子作者字段必填。
  3. 逻辑清晰化:拆分判断逻辑,先检查主对象值,再验证子作者数组,最后兜底,代码可读性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:15:00