A menudo uso objetos para pasar un conjunto de opciones.
En el 99,9% de estos casos, espero que estos objetos solo contengan un subconjunto de la propiedad que uso. Si una propiedad inesperada está presente, significa casi siempre que hay un error tipográfico o lógico.
¿Existe una forma sencilla de asegurarse de que los objetos de opción no contengan propiedades inesperadas? Realmente solo necesitaría esto durante las pruebas y la depuración, por lo que no tiene que ser eficiente.
Ejemplo:
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} )Sé que puedo implementarlo a través de una función que recibe los nombres de las propiedades esperadas:
function testOpts( opts={}, optNames=[] ) { /* ... */ } testOpts( opts, ["times", "silent", "logger"] )Pero mantener esto es aburrido y propenso a errores: cada vez que cambio una opción necesito actualizar esos parámetros. Lo probé y con demasiada frecuencia me olvido de actualizarlo, por lo que mi función sigue aceptando parámetros que eliminé, y esto es algo que quiero evitar.
¿Existe una solución mejor que me permita escribir los nombres de las propiedades solo una vez?
Si solo desea escribirlos una vez, la única forma de hacerlo es en la función de log donde los está utilizando. De hecho, hay una manera de hacerlo: use la sintaxis de descanso en la desestructuración y pruebe que no hay otras propiedades además de las esperadas (desestructuradas):
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`); } }Aparte de eso, use una herramienta de análisis estático como TypeScript o Flow, detectarán fácilmente estos errores.