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

能否在对象属性解构中使用空值合并运算符(??)处理TS的Maybe类型

解决方案

方案1:修改GraphQL Codegen配置(最推荐,一劳永逸)

你可以直接调整代码生成器的配置,让生成的Maybe<T>类型仅包含T | undefined,排除null值,这样原有解构默认值的写法完全不用改:
在你的codegen.yml配置文件中添加如下配置:

config:
  maybeValue: T | undefined
  avoidOptionals: false

如果需要连接口返回的null值也自动转成undefined,可以添加typescript-nullable-undefined插件,生成的请求工具会自动处理返回值中的null,完全适配你之前的解构写法。

方案2:封装null转undefined的预处理工具函数

如果不想改生成配置,可以写一个通用工具函数,把props里所有的null值批量转为undefined,之后直接用原有解构逻辑即可:

// 通用工具函数,支持深层处理
function nullsToUndefined<T extends Record<string, any>>(obj: T): {
  [K in keyof T]: T[K] extends null ? undefined :
  T[K] extends Record<string, any> ? ReturnType<typeof nullsToUndefined<T[K]>> :
  T[K]
} {
  return Object.fromEntries(
    Object.entries(obj).map(([key, value]) => {
      if (value === null) return [key, undefined]
      if (typeof value === 'object' && value !== null) return [key, nullsToUndefined(value)]
      return [key, value]
    })
  ) as any
}

// 组件内使用
export default function Example({ ExampleProps }) {
  const processedProps = nullsToUndefined(ExampleProps || {})
  const {
    content = "",
    title = "Missing Title",
    date = "",
    featuredImage = {},
    author = {},
    tags = [],
  } = processedProps;
  // 后续使用不需要再加可选链,TS能正确推导非空类型
}

方案3:解构后单独用空值合并运算符赋值

如果只有少数属性需要处理,不想加额外工具函数,可以直接单独赋值:

export default function Example({ ExampleProps }) {
  const content = ExampleProps?.content ?? ""
  const title = ExampleProps?.title ?? "Missing Title"
  const date = ExampleProps?.date ?? ""
  const featuredImage = ExampleProps?.featuredImage ?? {}
  const author = ExampleProps?.author ?? {}
  const tags = ExampleProps?.tags ?? []
  // 后续使用无需额外可选链
}
补充说明

关于你担心的可选链性能问题,2023年之后主流浏览器(Chrome、Firefox、Safari)都已经对可选链运算符做了深度优化,普通业务场景下的使用完全不会有可感知的性能差异,不需要过度担心。但过度使用可选链确实会降低代码可读性,优先用上面的方案统一处理null值会更利于维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:06:03