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

Typescript如何从嵌套对象的联合类型中排除undefined类型

问题原因

你之前的方案不生效,核心是没有匹配到你要处理的场景:

  • NonNullable<T>/Exclude<T,U> 仅能处理联合类型里的排除规则,你传入的是对象类型,自然不会生效
  • 自定义的NotOptional用的-?修饰符仅能移除属性的可选标记,你场景里的属性是必填、但值的类型包含undefined,不属于可选属性的范畴
  • 你的属性是嵌套结构,需要做递归处理才能处理到内层properties下的subtitle属性

解决方案

你可以自定义一个递归的深度排除undefined的工具类型,实现所有层级属性的undefined移除:

// 深度排除所有属性类型中的undefined
type DeepNonNullable<T> = T extends object ? {
  [K in keyof T]: DeepNonNullable<NonNullable<T[K]>>
} : NonNullable<T>

使用方式

直接套用到你定义的DefaultProperties上即可:

type Options = {
    id: number,
    text: string | undefined,
    properties: {
        title: string,
        subtitle: string | undefined,
    }
}

// 处理后的DefaultProperties所有属性都不含undefined
type DefaultProperties = DeepNonNullable<Pick<Options, "properties">>

效果验证

处理后的类型完全符合你的要求:

  • DefaultProperties['properties']['subtitle'] 类型为纯string,不含undefined
  • 如果需要对整个Options做处理,直接用DeepNonNullable<Options>即可,text属性也会变成纯string类型

业务场景使用示例

const options : Options = { 
  id: 1,
  text: undefined,
  properties: {
    title: "页面标题",
    subtitle: undefined
  }
};

// 这里定义defaults时,如果subtitle传undefined会直接报类型错误,符合默认值的校验要求
const defaults: DefaultProperties = { 
  properties: {
    title: "默认标题",
    subtitle: "默认副标题"
  }
};

const node : HTMLElement = document.createElement('div');
// 这里defaults.properties.subtitle是纯string,赋值给innerHTML不会再有类型报错
node.innerHTML = options.properties.subtitle ?? defaults.properties.subtitle;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:06:01