ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

es-toolkit 的 isSet:基于 instanceof 的 Set 类型守卫与 Lodash 兼容实现解析

es-toolkit 的 isSet:基于 instanceof 的 Set 类型守卫与 Lodash 兼容实现解析 es-toolkit 的 isSet基于 instanceof 的 Set 类型守卫与 Lodash 兼容实现解析【免费下载链接】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-toolkitisSet是 es-toolkit 提供的一个轻量级类型判断函数用于检测一个值是否为 JavaScript 内建的Set实例。它同时提供主库版本es-toolkit/predicate与 Lodash 兼容版本es-toolkit/compat两者实现完全一致并可作为 TypeScript 类型守卫使用。读完本文你将掌握isSet的 API 签名、与Map/WeakSet/数组/普通对象的区分行为、在集合运算与数据转换中的实战用法以及它在 es-toolkit 源码内部的实现原理与调用关系。函数概览一个instanceof的封装isSet的核心实现极简整个函数体只有一行基于 JavaScript 内建的instanceof运算符完成判断。主库实现位于 src/predicate/isSet.tsexport function isSet(value: unknown): value is Setany { return value instanceof Set; }关键点在于返回值类型被声明为value is Setany这是一个 TypeScript 类型谓词type predicate。当isSet(value)返回true时TypeScript 编译器会在后续代码中自动将value的类型收窄为Setany从而允许你直接访问size、has、add等 Set 专有成员而无需手动类型断言。Lodash 兼容版本位于 src/compat/predicate/isSet.ts它没有重复实现逻辑而是直接委托给主库版本import { isSet as isSetToolkit } from ../../predicate/isSet.ts; export function isSet(value?: any): value is Setany { return isSetToolkit(value); }两者唯一的差别是兼容版参数声明为value?: any可选参数这与 Lodash 允许无参调用返回 false的行为保持一致——这一点在兼容版的测试用例中有明确体现见下文测试分析。API 说明签名function isSet(value: unknown): value is Setany参数valueunknown需要判断是否为Set的值。返回值value is Setany若value是Set实例返回true否则返回false。基本用法从es-toolkit/compat导入import { isSet } from es-toolkit/compat; // Set 判断 const set new Set(); isSet(set); // true // 其他类型一律返回 false isSet(new Map()); // false isSet(new WeakSet()); // false isSet([]); // false isSet({}); // false isSet(set); // false isSet(123); // false isSet(null); // false isSet(undefined); // false与相似集合类型的区分Set与Map、WeakSet在形态上相似容易混淆isSet可以精确区分它们import { isSet } from es-toolkit/compat; // Set vs Map vs WeakSet isSet(new Set([1, 2, 3])); // true isSet(new Map([[key, value]])); // false isSet(new WeakSet()); // false // Set vs 数组 isSet(new Set([1, 2, 3])); // true isSet([1, 2, 3]); // false // Set vs 普通对象 isSet(new Set()); // true isSet({}); // false isSet(Object.create(null)); // false由于底层是instanceof Set任何非 Set 内建实例包括Object.create(null)创建的无原型对象都会得到false。实战场景类型守卫驱动集合运算主库文档 docs/reference/predicate/isSet.md 展示了isSet作为类型守卫在真实逻辑中的价值。最典型的场景是编写接受未知类型的通用集合处理函数让 TypeScript 自动完成类型收窄。计算集合大小function getCollectionSize(collection: unknown): number { if (isSet(collection)) { // TypeScript 在此处将 collection 推断为 Setany return collection.size; } if (Array.isArray(collection)) { return collection.length; } if (collection typeof collection object) { return Object.keys(collection).length; } return 0; } // 使用示例 getCollectionSize(new Set([1, 2, 3])); // 3 getCollectionSize([1, 2, 3]); // 3 getCollectionSize({ a: 1, b: 2 }); // 2如果没有类型谓词collection.size一行就会因为collection仍是unknown而无法通过编译isSet的value is Setany返回值让这段代码既安全又简洁。去重工具function removeDuplicates(data: unknown) { if (isSet(data)) { // 本身就是 Set原样返回 return data; } if (Array.isArray(data)) { return new Set(data); } // 其他类型不转换 return data; } const duplicatedArray [1, 2, 2, 3, 3, 3]; const uniqueSet removeDuplicates(duplicatedArray); console.log(uniqueSet); // Set { 1, 2, 3 } const existingSet new Set([a, b]); console.log(removeDuplicates(existingSet)); // Set { a, b }返回同一个 Set通用集合合并与交集计算isSet还可以用于编写同时接受Set与数组的混合集合运算函数// 通用集合合并 function mergeCollections(...collections: unknown[]): Setany { const result new Set(); for (const collection of collections) { if (isSet(collection)) { // 将 Set 中的所有值加入 result for (const item of collection) { result.add(item); } } else if (Array.isArray(collection)) { // 将数组中的所有值加入 result for (const item of collection) { result.add(item); } } } return result; } const set1 new Set([1, 2, 3]); const array1 [3, 4, 5]; const set2 new Set([a, b]); const merged mergeCollections(set1, array1, set2); console.log(merged); // Set { 1, 2, 3, 4, 5, a, b } // 计算集合交集 function getIntersection(coll1: unknown, coll2: unknown): Setany { const set1 isSet(coll1) ? coll1 : new Set(Array.isArray(coll1) ? coll1 : []); const set2 isSet(coll2) ? coll2 : new Set(Array.isArray(coll2) ? coll2 : []); const intersection new Set(); for (const item of set1) { if (set2.has(item)) { intersection.add(item); } } return intersection; } const setA new Set([1, 2, 3, 4]); const arrayB [3, 4, 5, 6]; const intersection getIntersection(setA, arrayB); console.log(intersection); // Set { 3, 4 }源码实现与调用链分析主库与兼容版的导出路径主库版本通过 src/predicate/index.ts 中的export { isSet } from ./isSet.ts对外导出可通过es-toolkit/predicate子路径或es-toolkit主入口引入。兼容版本通过 src/compat/compat.ts 中的export { isSet } from ./predicate/isSet.ts对外导出可通过es-toolkit/compat引入。从源码结构看兼容版的设计遵循薄封装原则所有判读逻辑只实现一次主库兼容层仅负责适配 Lodash 风格的调用习惯避免逻辑重复与潜在的实现漂移。内部的真实调用方isSet不仅是面向用户公开的 API也是 es-toolkit 内部其他工具函数的依赖这印证了它作为基础谓词的地位src/compat/util/toArray.ts 在将类数组、Map或Set转换为数组时调用了isSet用于决定是否走Array.from(value)的转换路径判断条件为isArrayLike(value) || isMap(value) || isSet(value)。src/util/serialize/serializeObject.ts 在序列化对象时调用isSet对Set类型进行专门的序列化处理。与WeakSet等边界情况的处理isSet使用instanceof Set判断而WeakSet与Set是不同的内建类二者不构成原型链关系因此new WeakSet()会正确返回false。这一边界行为在测试用例中得到了系统性的覆盖。测试验证行为契约的完整覆盖es-toolkit 为主库与兼容版分别维护了测试文件共同构成isSet的行为契约。主库测试 src/predicate/isSet.spec.ts 覆盖两类断言new Set()返回truenull、、123、{}、[]、new Map()、new WeakSet()等非 Set 值全部返回false。兼容版测试 src/compat/predicate/isSet.spec.ts 覆盖面更广重点验证与 Lodash 的行为对齐使用falseyfalsy 值集合来自 src/compat/_internal/falsey.ts逐一断言0、、NaN、null、undefined等 falsy 值均返回false通过isSet()无参调用验证兼容版的可选参数行为value?: any返回false对arguments对象、数组、布尔值、Date、Error、函数slice、普通对象、数字、正则、字符串、Symbol、WeakSet等逐一断言返回false额外覆盖了具有非函数constructor属性的对象这一 Lodash 时代遗留的 IE 11 兼容场景验证其返回false对应 src/compat/_internal/weakSet.ts 中导出的weakSet实例测试。从这些测试可以看出isSet的判定是严格且无歧义的只有真正的Set实例才返回true。主库版本 vs 兼容版本如何选择isSet在 es-toolkit 中有两个入口使用建议如下入口导入方式适用场景主库版本import { isSet } from es-toolkit/predicate或es-toolkit主入口新项目、现代代码风格推荐使用兼容版本import { isSet } from es-toolkit/compat从 Lodash 迁移、需要保持既有调用习惯的项目兼容版文档 docs/compat/reference/predicate/isSet.md 明确建议该兼容函数与主库实现相同应优先使用更现代的es-toolkit主库版本 isSet。两者的运行时行为一致差异仅在于兼容版为对齐 Lodash 而允许无参调用。如果你的代码库不需要 Lodash 兼容语义直接使用主库版本即可获得同样正确、体积更优的类型守卫。【免费下载链接】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),仅供参考
返回列表