TypeScript中NonNullable<any>类型的类型守卫不生效问题
TypeScript中NonNullable类型的类型守卫不生效问题
嘿,我来帮你捋捋这个问题!你写的defined函数本意是做一个通用的非空类型守卫,但这里有个关键小坑:你用了x is NonNullable<any>作为类型谓词,可NonNullable<any>本质上还是any类型——毕竟any本身就涵盖了所有非null/undefined的值,TypeScript根本没法通过这个谓词把x的类型从string | undefined收窄成你想要的string。
咱们来改一下这个类型守卫,把它改成泛型版本就能解决问题了:
function defined<T>(x: T): x is NonNullable<T> { return (x !== undefined) && (x !== null) }
这样修改之后,当你传入string | undefined类型的x时,TypeScript会自动把T推断成string | undefined,NonNullable<T>就会被解析成string。这时候再看logit函数里的判断:
if (defined(x)) { y = x; // 这里x会被正确收窄成string类型,不会报错 }
为什么原来的写法不行呢?再给你拆解下:NonNullable<any>等价于any,因为any类型不受NonNullable的约束,TypeScript看到x is any这种谓词时,不会做任何有效的类型收窄,所以在if块里x还是原来的string | undefined,赋值给y: string自然就会触发类型错误啦。
你把代码改成泛型版本后,再运行logit('abc')和logit(undefined),就能正常工作,也不会有类型报错了。
备注:内容来源于stack exchange,提问作者John Deighan
相关产品推荐
相关产品推荐

