如何在TypeScript类型层面断言某个类型不是any
核心原理
any是TypeScript的特殊顶层类型,默认可以匹配任意extends约束,因此原有实现无法校验any类型。首先需要使用准确的IsAny类型判断,再改造Assert的泛型约束即可实现需求。
完整实现代码
// 通用精准的IsAny判断实现 type IsAny<T> = 0 extends (1 & T) ? true : false // 改造后的Assert泛型,新增any校验能力 type Assert<A extends IsAny<A> extends true ? never : ShouldBe, ShouldBe> = A
测试验证
所有原有测试用例行为保持不变,同时新增的any校验可以正常触发:
// @ts-expect-error 符合预期报错 type SubsetObj = Assert<{ id: string }, { id: string; name: string }> type SameObj = Assert< { id: string; name: string }, { id: string; name: string } > type ExceedsObj = Assert<{ id: string; name: string }, { id: string }> type SubsetUnion = Assert<number, number | string> type SameUnion = Assert<number | string, number | string> // @ts-expect-error 符合预期报错 type ExceedUnion = Assert<number | string, number> // @ts-expect-error 现在可以正常触发any类型的校验错误,符合要求 type AnyShouldWork = Assert<any, number> // unknown校验行为和之前一致 // @ts-expect-error 符合预期报错 type AssertUnknown = Assert<unknown, number>
IsAny实现逻辑说明
对于除any之外的所有类型,1 & T会返回和数值1的交叉类型,不可能包含数值0,因此0 extends (1 & T)返回false;只有当T为any时,1 & any返回any,0 extends any成立,因此可以100%准确判断any类型。
内容的提问来源于stack exchange,提问作者Chet
相关产品推荐
相关产品推荐

