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

TypeScript 自定义递归剔除空值类型无法访问嵌套键问题

问题原因
  • 你实现的OmitNullishKeys工具类型没有预先排除输入泛型T本身携带的null | undefined值,就直接取keyof T进行遍历:当T是包含null/undefined的联合类型时,keyof T会返回never(因为null/undefined没有任何属性,联合类型取属性键的逻辑是取所有成员共有的属性键,没有共有键就返回never),此时TypeScript无法对映射类型做进一步展开计算,会保留原始的OmitNullishKeys<xxx>包装类型,自然无法识别到内部的forums属性。
  • 当前实现也没有兼容可选属性的处理逻辑,可选属性的类型默认隐式包含undefined,也需要提前剔除。
修复方案

在处理泛型T的第一步先排除nullish值,再做后续递归处理,修正后的工具类型代码如下:

export type OmitNullish<T> = Exclude<T, null | undefined>;
export type OmitNullishKeys<T> = 
  // 先剔除T本身的null/undefined,得到非空类型U
  OmitNullish<T> extends infer U 
  ? U extends Record<string | number | symbol, any>
    ? {
        // 遍历U的所有属性键,移除可选标记
        [K in keyof U]-?: U[K] extends boolean | string | number | symbol
          ? OmitNullish<U[K]>
          : OmitNullishKeys<U[K]>
      }
    // 如果U是基础类型,直接返回剔除nullish后的结果
    : OmitNullish<U>
  : never;
效果验证

用你提供的测试代码验证,不会再抛出属性不存在的错误:

export type RandomObj = OmitNullishKeys<{
    stackOverflow: {
        forums?: {
            thread1: 'not available';
        } | null;
    } | null;
}>;
// 可以正常访问嵌套属性
export type RandomObjectAccessed = RandomObj['stackOverflow']['forums'];
// 推导的类型结果为:{ thread1: 'not available' }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:24:07