Hi,
I'm having difficultly trying to work out how to handle objects with optional properties.
A common JavaScript pattern is to simulate keyword arguments with an options argument, e.g.
var myX = new X({
foo: 1
bar: 'xyzzy'
});
The question is: how do I best represent this options object with the Closure Compiler?
If I use a typedef like:
/**
* @typedef {{foo: number, bar: (string|undefined)}}
*/
MyOptions;
where bar is optional, then the following work:
/** @type {MyOptions} */
var a = {foo: 1, bar: 'xyzzy'}; // All properties defined
/** @type {MyOptions} */
var b = {foo: 1, bar: undefined}; // All properties defined
/** @type {MyOptions} */
var c = /** @type {MyOptions} */ ({foo: 1}); // Typecast
but the desired use case does not:
/** @type {MyOptions} */
var d = {foo 1}; // bar is not present, raises type error
Note that a and b behave differently from c and d, so it is entirely reasonable that the compiler complains about d (we override it in c).
a.hasOwnProperty('bar'); // -> true
b.hasOwnProperty('bar'); // -> true
c.hasOwnProperty('bar'); // -> false, but we cheated
d.hasOwnProperty('bar'); // -> false, so d is not an instance of MyOptions
Any hints on how to best handle this? Ideally I'd like to write an object literal like d and have the compiler interpret it as a MyOptions type, without needing a typecast.
Cheers,
Tom