TypeScript如何判断变量为any类型?typeof报错解决方法
我可通过如下代码检查变量是否为string类型:
if (typeof myVariable === "string") { }
但现在我需要判断变量是否为any类型,尝试使用如下代码实现校验:
if (typeof myVariable === "any") { }
运行代码后触发TS编译报错,提示信息为:
该条件将始终返回'false',因为类型
"string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"与"any"没有重叠。ts(2367) 无效的typeof比较值。
请问该问题应如何解决?
报错核心原因
any是TypeScript编译阶段的专属静态类型标记,不存在于JavaScript运行时环境中。而typeof是JavaScript运行时运算符,它的返回值仅包含固定的8种字符串类型(即报错信息中列出的取值集合),永远不会返回"any"字符串。因此直接将typeof的结果和"any"做比较属于逻辑上不成立的无效操作,TS会直接拦截这类无效比较。
分场景解决方法
编译期判断变量的TS静态类型是否为any
如果需求是在类型层面对变量的类型做校验,不需要编写运行时代码,可通过TS类型编程实现通用判断:
type IsAny<T> = 0 extends 1 & T ? true : false; // 类型校验效果 type CheckAny = IsAny<any>; // 推导结果为true type CheckString = IsAny<string>; // 推导结果为false type CheckNumber = IsAny<number>; // 推导结果为false
该判断利用了any的类型吸收特性:任意类型与any交叉后的结果仍为any,而只有当交叉结果为any时,才会满足0 extends 1 & T的条件判断。
如果使用TS 4.7以上版本,也可以直接使用成熟的社区类型工具库提供的现成IsAny工具类型,无需手动实现。
运行时判断传入值的类型
需要明确的是:TypeScript编译完成后,所有静态类型标记都会被完全擦除,运行时拿到的只有纯JavaScript值,根本无法区分某个传入的值是原本声明为any类型的变量,还是普通的原生JS类型值。
这种场景下不需要额外判断所谓的any类型,直接按照JavaScript原生的类型判断逻辑处理即可:
- 如果需求是兼容任意类型的值,直接使用变量即可,无需做类型拦截
- 如果需要过滤特殊值,针对JS运行时可识别的类型(如
undefined、null、function等)编写对应的判断逻辑即可。
快速规避现有代码的TS报错
如果是旧代码中误用了typeof x === "any"这类无效判断,直接删除该行代码即可——该判断从逻辑上永远不会成立,属于完全无意义的冗余逻辑。
内容的提问来源于stack exchange,提问作者Agung

