es-toolkit 的 isBoolean 详解:Lodash 兼容的布尔类型判断与 TypeScript 类型守卫
【免费下载链接】es-toolkitA modern JavaScript utility library that's 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit
isBoolean是 es-toolkit 中用于判断值是否为 boolean 类型(含 Boolean 对象包装器)的类型安全函数。本文以 compat 兼容层中的 isBoolean 文档 为骨架,结合 源码实现 与 测试用例 深入讲解其行为边界、与原生typeof的取舍、与 es-toolkit 严格 API 版本的差异,以及从 Lodash 迁移时的实际用法。
一、函数概览:签名、参数与返回值
isBoolean位于es-toolkit/compat兼容层,其调用签名与 Lodash 完全一致:
const result = isBoolean(value);| 项目 | 说明 |
|---|---|
参数value | unknown类型,即要判断是否为 boolean 的任意值 |
| 返回值 | value is boolean:若值为 boolean 类型返回true,否则返回false |
| 类型守卫 | 是 TypeScript 类型谓词(type predicate),可收窄参数类型 |
从源码看,compat 版本的实现非常简洁,核心逻辑只有一行:
export function isBoolean(value?: any): value is boolean { return typeof value === 'boolean' || value instanceof Boolean; }实现位于 src/compat/predicate/isBoolean.ts,由两个条件组成:
typeof value === 'boolean':命中true/false两个原始值(primitive);value instanceof Boolean:命中new Boolean(true)这类 Boolean 对象包装器。
两个条件任意成立即判定为 boolean。注意参数被声明为value?: any,这是兼容层为了与 Lodash 行为 1:1 对齐而保留的宽松签名(详见后文与严格 API 的对比)。
二、使用方式与行为对照
在 TypeScript 项目中,从 compat 入口导入并使用:
import { isBoolean } from 'es-toolkit/compat'; // 原始 boolean 值 isBoolean(true); // true isBoolean(false); // true // Boolean 对象包装器 isBoolean(new Boolean(true)); // true isBoolean(new Boolean(false)); // true // 其他类型一律返回 false isBoolean(0); // false isBoolean(1); // false isBoolean('true'); // false isBoolean('false'); // false isBoolean(null); // false isBoolean(undefined); // false isBoolean({}); // false isBoolean([]); // false判断边界速查表
| 输入 | 结果 | 原因 |
|---|---|---|
true/false | true | typeof为'boolean' |
new Boolean(true)/new Boolean(false) | true | instanceof Boolean成立 |
0/1/NaN/''/null/undefined | false | 均为非 boolean 类型 |
'true'/'false'字符串 | false | 字符串不会隐式转换 |
{}/[]/ 函数 / 正则 / Date 等 | false | 不属于 boolean 家族 |
值得强调的是:字符串'true'、'false'、数字0、1都不会被误判为 boolean,这一点与某些语言或宽松框架的行为不同,符合 Lodash 的语义。
三、为什么文档建议优先使用typeof运算符
官方文档在开头用醒目警告提出了建议:
请使用
typeof运算符。isBoolean函数因处理 Boolean 对象包装器而变得复杂。建议改用更简单、更现代的typeof value === 'boolean'。
其背后的原因是:为了兼容 Lodash 行为,compat 版isBoolean必须额外处理new Boolean()包装器,这引入了instanceof判断。而实际项目中几乎不会出现 Boolean 包装器对象,绝大多数场景下直接写:
const isBool = typeof value === 'boolean';更直接、零函数调用开销、也无须处理instanceof的边界问题。因此:
- 若你正在新写代码或使用 es-toolkit 的严格 API,建议直接用
typeof或严格版isBoolean; - 若你在迁移存量 Lodash 代码,为了不改动调用点,可使用 compat 版
isBoolean保持行为一致。
四、源码级解析:兼容层实现与严格版实现的差异
4.1 兼容层(compat)实现
src/compat/predicate/isBoolean.ts 完整实现如下:
export function isBoolean(value?: any): value is boolean { return typeof value === 'boolean' || value instanceof Boolean; }它额外判断了 Boolean 包装器,这是 Lodash 行为的一部分——Lodash 的isBoolean同样对new Boolean()返回true。
4.2 严格 API(es-toolkit 主入口)实现
主包(非 compat)中的 src/predicate/isBoolean.ts 则只保留最纯粹的判断:
export function isBoolean(x: unknown): x is boolean { return typeof x === 'boolean'; }两个版本的差异总结:
| 对比维度 | es-toolkit(严格 API) | es-toolkit/compat |
|---|---|---|
| 参数类型 | unknown,类型更严格 | any,与 Lodash 签名对齐 |
| 是否识别 Boolean 包装器 | 否 | 是(instanceof Boolean) |
| 语义 | 纯原始 boolean | Lodash 兼容语义 |
| 典型使用场景 | 新代码、类型安全优先 | 迁移存量 Lodash 代码 |
从 src/predicate/index.ts 可以看到,严格版isBoolean会从es-toolkit主入口导出;而 compat 版从 src/compat/compat.ts 的es-toolkit/compat入口导出。这也印证了 compat 层的设计初衷——与 Lodash 1:1 对齐(含隐式类型转换、多重参数形态等),代价是体积与运行开销略大,详见 docs/compat/intro.md。
五、测试用例验证:行为边界有据可查
compat 版isBoolean的行为边界由 src/compat/predicate/isBoolean.spec.ts 中的 Vitest 用例完整覆盖:
正向用例——以下输入均应返回true:
isBoolean(true); // true isBoolean(false); // true isBoolean(Object(true)); // true isBoolean(Object(false)); // true反向用例——以下输入均应返回false:arguments对象、数组、Date、Error、函数(slice)、普通对象、数字、正则、字符串、Symbol 等。
测试还借助 src/compat/_internal/falsey.ts 中的假值集合[, null, undefined, false, 0, NaN, '']做了系统性验证:对每个假值调用isBoolean,只有false本身返回true(即falsey.map(value => value === false)与falsey.map(value => isBoolean(value))结果完全一致)。这从侧面确认了:undefined、null、0、NaN、空字符串这些常见的"类布尔"陷阱值都不会被误判。
六、在 TypeScript 中使用类型守卫
isBoolean的返回类型被声明为value is boolean,因此它天然是 TypeScript 的类型守卫(type predicate),可以直接用于条件分支收窄类型:
import { isBoolean } from 'es-toolkit/compat'; function process(value: unknown) { if (isBoolean(value)) { // 此处 value 已被收窄为 boolean 类型 return value ? 'yes' : 'no'; } // 此处 value 仍为 unknown return String(value); }在if分支内 TypeScript 编译器会依据类型谓词将value从unknown收窄为boolean,从而避免手写类型断言,提升代码的类型安全性。严格版isBoolean(参数为unknown)同样具备这一能力,且由于不包含instanceof分支,收窄语义更为纯粹。
七、迁移与使用建议总结
- 新项目、新代码:优先使用
typeof value === 'boolean',或从es-toolkit主入口导入严格版isBoolean,类型更严格、体积更小、语义更纯粹。 - 存量 Lodash 代码库:将
import isBoolean from 'lodash/isBoolean'替换为import { isBoolean } from 'es-toolkit/compat'(或import isBoolean from 'es-toolkit/compat/isBoolean'按需引入),无需改动调用点即可获得与 Lodash 一致的行为。 - 需要处理 Boolean 包装器:若确实存在
new Boolean()产生的对象(例如来自旧代码或某些序列化框架),必须使用 compat 版isBoolean,严格版与typeof均无法识别。 - 性能与体积敏感场景:
isBoolean是 O(1) 的常量级判断,无任何遍历或递归;在热路径中直接使用typeof可省去一次函数调用。
相关资源
- compat 版实现:src/compat/predicate/isBoolean.ts
- 严格版实现:src/predicate/isBoolean.ts
- compat 版测试:src/compat/predicate/isBoolean.spec.ts
- 兼容层设计说明:docs/compat/intro.md
- 兼容层导出入口:src/compat/compat.ts
【免费下载链接】es-toolkitA modern JavaScript utility library that's 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考