关于带NonNullable<any/unknown>类型谓词的Type Guard类型收窄问题咨询
TypeScript类型守卫中NonNullable与NonNullable的收窄差异解析
一、使用NonNullable<any>的异常收窄结果
当类型守卫的类型谓词设为x is NonNullable<any>时,会出现不符合预期的收窄表现:
- true分支中变量
a的类型仍为string | undefined,未被正确收窄 - false分支中变量
a的类型为never,说明类型守卫判定“不可能进入此分支”
示例代码:
function defined1(x: unknown): x is NonNullable<any> { return (x !== undefined) && (x !== null) } let a : string | undefined; if (defined1(a)) { a // 观察到的类型:string | undefined } else { a // 观察到的类型:never }
原因分析
NonNullable<any>本质等价于any——因为any类型本身就包含null和undefined,类型守卫的谓词实际变成了x is any。在类型收窄时:
- true分支中,原类型
string | undefined与any的交集仍是string | undefined,所以类型没有变化 - false分支中,原类型里不存在任何不属于
any的类型,因此被收窄为never
二、使用NonNullable<unknown>的预期收窄结果
当类型守卫的类型谓词设为x is NonNullable<unknown>时,收窄结果符合预期:
- true分支中变量
a的类型被收窄为string - false分支中变量
a的类型被收窄为undefined
示例代码:
function defined2(x: unknown): x is NonNullable<unknown> { return (x !== undefined) && (x !== null) } if (defined2(a)) { a // 观察到的类型:string } else { a // 观察到的类型:undefined }
原因分析
NonNullable<unknown>代表排除了null和undefined的unknown类型,即所有非空、非undefined的类型集合。在类型收窄时:
- true分支中,原类型
string | undefined与NonNullable<unknown>的交集是string,因此类型被正确收窄 - false分支中,剩下的类型就是
undefined,完全匹配守卫的逻辑判断
内容的提问来源于stack exchange,提问作者WeDoTheBest4You
相关产品推荐
相关产品推荐

