TypeScript库供JavaScript调用时,如何校验构造函数的Set类型参数?
解决TypeScript库被JavaScript调用时的Set参数校验问题
嘿,你的校验思路方向是对的,但这里有个容易踩的坑——用instanceof Set做校验,在跨执行上下文的场景(比如iframe、Web Worker,或者某些模块隔离环境)下可能会失效。因为不同上下文里的Set构造函数是独立的引用,哪怕是原生Set,instanceof也会返回false。
给你一个更可靠的校验方案,兼顾兼容性和严谨性:
export class Something { private mySet: Set<string>; constructor(aSet: Set<string>) { // 多维度校验确保是有效的Set if ( typeof aSet !== 'object' || aSet === null || Object.prototype.toString.call(aSet) !== '[object Set]' || typeof aSet.add !== 'function' || typeof aSet.has !== 'function' || typeof aSet.delete !== 'function' ) { throw new TypeError('Invalid parameter: expected a valid Set instance'); } this.mySet = aSet; } }
为什么这么做?
typeof aSet !== 'object' || aSet === null:先排除非对象和null的情况,避免后续调用方法报错Object.prototype.toString.call(aSet) !== '[object Set]':这是判断原生对象类型的“黄金标准”,不管执行上下文如何,原生Set都会返回这个字符串,比instanceof更可靠- 检查
add/has/delete方法:避免遇到那些手动模拟了Set结构但没有实现核心方法的伪Set对象,让校验更严谨
如果你的场景不需要考虑自定义的Set子类,只需要校验原生Set,那可以简化成只保留toString的判断,但加上方法检查能让你的库更健壮。
另外要提醒的是:虽然TypeScript的类型标注能在编译时帮你把关,但JavaScript调用者没有类型约束,所以运行时校验是必不可少的,这一步你已经考虑到了,非常棒!
内容的提问来源于stack exchange,提问作者Bambou
相关产品推荐
相关产品推荐

