You need to enable JavaScript to run this app. TypeScript处理GraphQL返回数据时提升嵌套对象属性一层的最佳实践
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript处理GraphQL返回数据时提升嵌套对象属性一层的最佳实践

TypeScript 下处理 GraphQL 返回多余嵌套层级的最佳实践

针对Apollo Client自动生成类型的场景,推荐以下3种从优到劣的方案,全部满足类型安全要求:

方案1:使用无副作用的映射函数转换(最推荐)

不要直接修改Apollo返回的原始查询对象(会有缓存异常风险),单独写映射函数生成你需要的扁平化结构,类型完全可控:

// Apollo 自动生成的原始查询类型
interface GeneratedPost {
  id: string
  title: string
  featuredImage?: {
    node?: {
      url: string
      altText: string
    }
  }
}

// 自定义扁平化后的业务使用类型
interface CleanedPost {
  id: string
  title: string
  featuredImage?: {
    url: string
    altText: string
  }
}

// 类型安全的转换函数
const cleanPostData = (rawData: GeneratedPost): CleanedPost => {
  return {
    ...rawData,
    featuredImage: rawData.featuredImage?.node
  }
}

// 拿到查询结果后先转换再使用
const { data } = useQuery(GET_POST)
const cleanedData = data ? cleanPostData(data) : undefined

方案2:手动扩展类型修改原对象(仅适合临时场景)

如果你确实需要修改原对象,可以先扩展自动生成的类型,避免赋值报错:

// 扩展原始类型,允许featuredImage为两种结构
type MutablePost = GeneratedPost & {
  featuredImage?: GeneratedPost['featuredImage'] | CleanedPost['featuredImage']
}

const mutableData = data as MutablePost
if (mutableData?.featuredImage) {
  mutableData.featuredImage = mutableData.featuredImage.node
}

方案3:通用脱壳工具函数(适合大量重复嵌套场景)

如果你的GraphQL返回有大量{node: T}结构的嵌套,写通用工具函数复用逻辑:

type NodeWrapper<T> = { node?: T }
const unwrapNode = <T>(wrapper: NodeWrapper<T> | undefined): T | undefined => {
  return wrapper?.node
}

// 多字段复用非常便捷
const cleanPostData = (raw: GeneratedPost): CleanedPost => ({
  ...raw,
  featuredImage: unwrapNode(raw.featuredImage),
  author: unwrapNode(raw.author),
  category: unwrapNode(raw.category)
})

额外优化建议

如果你使用GraphQL Code Generator生成类型,可以配置自定义插件自动生成转换逻辑,不需要手动编写扁平化类型和映射函数,进一步减少重复工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 22:24:06