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
相关产品推荐
相关产品推荐

