ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

es-toolkit 的 isIterable:用类型守卫优雅判定可迭代对象

es-toolkit 的 isIterable:用类型守卫优雅判定可迭代对象 es-toolkit 的 isIterable用类型守卫优雅判定可迭代对象【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkitisIterable是 es-toolkit 提供的一个类型谓词type predicate函数用于判断一个值是否实现了 JavaScript 的可迭代协议即拥有Symbol.iterator方法。它适用于对未知类型数据unknown做安全校验与类型收窄例如在解析 JSON、处理用户输入或实现通用数据转换工具时先确认目标可被for...of、展开运算符或Array.from消费。读完本文你将掌握isIterable的完整用法、底层判定原理、边界行为以及在 lodash 兼容层toArray中的真实应用场景。isIterable 是什么在 JavaScript 中可迭代iterable 指对象实现了迭代协议——即对象上存在Symbol.iterator方法可以被for...of循环、展开运算符...、Array.from()等语法与 API 消费。es-toolkit 的isIterable正是对这一能力的运行时检测函数const result isIterable(value);从源码实现看判定逻辑非常精简核心只有一行见 src/predicate/isIterable.tsexport function isIterable(value: unknown): value is Iterableunknown { return value ! null typeof (value as { [Symbol.iterator]?: unknown })[Symbol.iterator] function; }它做了两件事空值兜底value ! null同时排除null与undefined避免对其访问属性时抛错协议检测读取值的Symbol.iterator属性并判断其类型是否为function。只要该方法存在且可调用该值就被视为可迭代对象。需要注意的是这里检测的是拥有Symbol.iterator方法这一协议本身而不是能否成功迭代。某些对象即使声明了Symbol.iterator迭代时仍可能抛错例如生成器已处于关闭状态这一点在使用时值得留意。基本用法函数签名function isIterable(value: unknown): value is Iterableunknown参数valueunknown需要判定的值可以是任意类型返回值value is Iterableunknown即当返回true时TypeScript 会将value的类型收窄为Iterableunknown。典型调用示例import { isIterable } from es-toolkit/predicate; // 可迭代的值 console.log(isIterable([1, 2, 3])); // true console.log(isIterable(abc)); // true console.log(isIterable(new Set([1, 2, 3]))); // true console.log(isIterable(new Map())); // true // 不可迭代的值 console.log(isIterable({ a: 1 })); // false console.log(isIterable(123)); // false console.log(isIterable(null)); // false从 src/predicate/isIterable.spec.ts 的测试用例可以确认isIterable对以下值均返回true数组[]、[1, 2, 3]字符串、abcSet与Mapnew Set([1, 2])、new Map()TypedArraynew Uint8Array([1, 2])生成器对象function* gen() { yield 1; }调用后返回的gen()自定义可迭代对象只要实现了*[Symbol.iterator]() { ... }方法即可。对以下值返回false普通对象{}、{ a: 1 }不可迭代的原始值123、true、Symbol(x)null与undefined。遍历自定义可迭代对象只要对象提供了Symbol.iterator方法即使不是内建类型也会被判定为可迭代const custom { *[Symbol.iterator]() { yield 1; yield 2; yield 3; }, }; console.log(isIterable(custom)); // true console.log([...custom]); // [1, 2, 3]这一点在测试中亦有覆盖见 src/predicate/isIterable.spec.ts说明isIterable判定的是协议而非具体类型具有良好的扩展性。作为 TypeScript 类型守卫使用isIterable的返回类型是value is Iterableunknown因此它可以直接充当类型守卫type guard在条件分支中自动收窄类型让编译器理解该分支内value已具备迭代能力function collect(value: unknown): unknown[] { // 在这个分支内value 被收窄为 Iterableunknown if (isIterable(value)) { return [...value]; } return []; }对应测试见 src/predicate/isIterable.spec.ts验证了收窄后的值可以直接使用展开运算符const value: unknown [1, 2, 3]; if (!isIterable(value)) { throw new Error(expected an iterable); } expect([...value]).toEqual([1, 2, 3]);这意味着在编写处理unknown数据的工具函数、运行时校验库或 JSON 反序列化逻辑时isIterable既能完成运行时防护又能免去手写类型断言as Iterableunknown让类型安全贯穿整个分支。在项目中的实际应用lodash 兼容层的 toArrayisIterable并非孤立存在它已被 es-toolkit 自身集成使用。在 lodash 兼容实现 src/compat/util/toArray.ts 中toArray负责把任意值转换为数组其转换逻辑按优先级依次为null/undefined→ 返回[]类数组isArrayLike、Map、Set→ 直接用Array.from(value)转换普通对象先检查是否为可迭代对象若是则用Array.from(value)展开否则取Object.values(value)其他情况 → 返回[]。其中第 3 步正是借助isIterable完成的见 src/compat/util/toArray.tsif (typeof value object) { if (isIterable(value)) { return Array.from(value); } return Object.values(value); }这个例子展示了isIterable在生产代码中的典型用法在对象类型内部进一步区分可迭代对象与普通对象从而决定采用展开转换还是枚举属性转换行为与 lodash 的_.toArray保持一致。此外在函数式编程模块 src/fp/pipe.ts 中管道执行逻辑也通过isIterable判断中间输出是否可迭代以决定惰性分组lazy group的短路行为——可见该函数是 es-toolkit 内部基础设施的一部分而非仅面向用户的辅助工具。与其他类型判断的组合使用isIterable位于 src/predicate/index.ts 的统一导出中与isArray、isString、isMap、isSet、isTypedArray、isPlainObject等 30 余个谓词一同提供可按需从es-toolkit/predicate子路径按名引入import { isIterable, isPlainObject, isTypedArray } from es-toolkit/predicate;在需要精细化区分数据形状时可以组合使用。例如同时判定是可迭代对象但不是普通对象或区分字符串可迭代与数组可迭代的差异处理function stringifyEntries(value: unknown): string { if (!isIterable(value)) { return String(value); } // 字符串按字符迭代Map 按 [key, value] 对迭代 return Array.from(value as Iterableunknown).map(String).join(, ); }边界情况与注意事项null与undefined恒为false实现中通过value ! null直接短路不会抛错函数是否可迭代取决于实现普通函数没有Symbol.iterator返回false但生成器函数调用后返回的生成器对象是可迭代的返回true判定协议而非迭代成功性isIterable只检查Symbol.iterator是否存在且为函数不保证for...of一定成功执行类型收窄是静态层面的收益运行时行为与类型无关即使value声明为unknown只要实现协议就会被判定为true子路径导入从es-toolkit/predicate导入可享受更优的 tree-shaking 效果仅打包用到的函数。小结isIterable以一行核心判定逻辑为值是否可迭代提供了运行时检测与编译期类型收窄的双重能力。无论是处理动态数据、编写通用转换工具还是像 es-toolkit 自身的toArray、pipe那样做内部逻辑分支它都是构建健壮 JavaScript/TypeScript 代码的可靠基础件。结合 src/predicate/isIterable.ts 的实现与 src/predicate/isIterable.spec.ts 的完整测试覆盖你可以在自己的项目中放心复用它。【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表