检测意外属性
Detecting unexpected properties
我经常使用对象来传递一组选项。
在 99.9% 的情况下,我希望这些对象只包含我使用的 属性 的一个子集。如果出现意想不到的 属性,这几乎总是意味着存在拼写错误或逻辑错误。
有没有一种简单的方法可以确保选项对象不包含意外属性?我只在测试和调试期间真正需要它,所以它不一定是高效的。
示例:
function log( text, opts={} ) {
const {times=1, silent=false, logger=console} = opts
if (silent) return
for (let i=0; i<times; i++) {
logger.log( text )
}
}
// all good here
log( "Hello World!", {times:1} )
// "slient" is not a valid option. It's a typo.
// I want this call to throw an exception.
log( "Bye World!", {times:2, slient:true} )
我知道我可以通过接收预期属性名称的函数来实现它:
function testOpts( opts={}, optNames=[] ) { /* ... */ }
testOpts( opts, ["times", "silent", "logger"] )
但是维护这个很无聊而且容易出错:每次我改变一个选项我都需要更新那些参数。我试过了,但我经常忘记更新它,所以我的函数一直接受我删除的参数,这是我想避免的事情。
有没有更好的解决方案让我只写一次 属性 个名字?
如果您只想编写一次,唯一的方法是在您使用它们的 log
函数中。确实有一种方法可以做到这一点:使用 rest syntax in the destructuring,并测试除了预期的(解构的)属性之外没有其他属性:
function log( text, opts={} ) {
const {times=1, silent=false, logger=console, ...rest} = opts
// ^^^^^^^
assertEmpty(rest);
if (silent) return
for (let i=0; i<times; i++) {
logger.log( text )
}
}
function assertEmpty(val) {
const keys = Object.keys(val);
if (keys.length) {
throw new RangeError(`Unexpected properties ${keys.join(', ')} in object`);
}
}
除此之外,使用TypeScript或Flow等静态分析工具,他们很容易发现这些错误。
我经常使用对象来传递一组选项。
在 99.9% 的情况下,我希望这些对象只包含我使用的 属性 的一个子集。如果出现意想不到的 属性,这几乎总是意味着存在拼写错误或逻辑错误。
有没有一种简单的方法可以确保选项对象不包含意外属性?我只在测试和调试期间真正需要它,所以它不一定是高效的。
示例:
function log( text, opts={} ) {
const {times=1, silent=false, logger=console} = opts
if (silent) return
for (let i=0; i<times; i++) {
logger.log( text )
}
}
// all good here
log( "Hello World!", {times:1} )
// "slient" is not a valid option. It's a typo.
// I want this call to throw an exception.
log( "Bye World!", {times:2, slient:true} )
我知道我可以通过接收预期属性名称的函数来实现它:
function testOpts( opts={}, optNames=[] ) { /* ... */ }
testOpts( opts, ["times", "silent", "logger"] )
但是维护这个很无聊而且容易出错:每次我改变一个选项我都需要更新那些参数。我试过了,但我经常忘记更新它,所以我的函数一直接受我删除的参数,这是我想避免的事情。
有没有更好的解决方案让我只写一次 属性 个名字?
如果您只想编写一次,唯一的方法是在您使用它们的 log
函数中。确实有一种方法可以做到这一点:使用 rest syntax in the destructuring,并测试除了预期的(解构的)属性之外没有其他属性:
function log( text, opts={} ) {
const {times=1, silent=false, logger=console, ...rest} = opts
// ^^^^^^^
assertEmpty(rest);
if (silent) return
for (let i=0; i<times; i++) {
logger.log( text )
}
}
function assertEmpty(val) {
const keys = Object.keys(val);
if (keys.length) {
throw new RangeError(`Unexpected properties ${keys.join(', ')} in object`);
}
}
除此之外,使用TypeScript或Flow等静态分析工具,他们很容易发现这些错误。