Specifying optional properties on object parameter

Short version:
We want to be able to use the following JSDoc info (or similar) on an Object parameter without all properties being required by the error checking mechanism in Developer:

* @param {{tMessage:String, tTo:String, tSubject:String;, aAttachments:Array<String>, tFrom:String, tCC:String, tBCC:String, dQueueEmail:Date}} emailProperties

Long version:
Ideally, we want to use a single parameter of type Object, and then supply properties as necessary. We can then handle properties that were not included with defaults, etc. Ideally, we could use the following (or similar):

/**
 * @param {{tMessage:String, tTo:String, tSubject:String;, aAttachments:Array<String>, tFrom:String, tCC:String, tBCC:String, dQueueEmail:Date}} emailProperties 
 */
function SendEmail(emailProperties) 
{	
  // do stuff
}

The problem here, is that when we try to call this method without supplying all of the properties, we get a warning in Developer. I realize that it still functions, but I don’t want to have thousands of these warnings spread throughout our solution, nor do I want to disable the error checking and go without the system keeping us honest (I know, I’m a dreamer). By doing the following, we are able to use this method without being forced to supply all of the potential properties the method might use.

* @param {Object} emailProperties

The problem with the above is that as we work in the code within the method, we get warnings on each reference to a properly telling us that it is not defined. We are also unable to benefit from the Intellisense as we code. I have read enough to see that a solution is to exclude the type in the JSDoc as follows:

* @param emailProperties

The problem with this is that there is no Intellisense or error checking. I’m aware that when you declare parameters, you can specify in the JSDoc that they are optional. However, I don’t see how you can do this with the properties of an object. I’m also aware that we can suppress the warnings on each of the methods that call the method above…which would be nearly every method we write…no thanks. Does anyone have a solution to this?

Maybe you could try:

/** 
 * @param {Object} obj
 */
function SendEmail(obj) 
{   
  /** @type {{tMessage:String, tTo:String, tSubject:String;, aAttachments:Array<String>, tFrom:String, tCC:String, tBCC:String, dQueueEmail:Date}} */
  var emailProperties = obj;
  // do stuff with emailProperties
}

A bit like you would cast in Java…

Thanks Patrick,

That will definitely provide for the error checking within the method (which I must acknowledge is an improvement). I’d still like to be able to have the Intellisense available when writing a call to it. Is that possible?

[As an aside, what do we call it if not Intellisense? That’s a Microsoft-only term isn’t it?]

It’s usually called auto complete in Eclipse.

I just tried another thing:

/**
 * @param {{a: String, [b]: Boolean}} param
 */
function testing(param) {
	application.output(param.a);
	if (param.b) {
		application.output(param.b);
	}
}

function callTesting() {
	var obj = {a: "test"};
	testing(obj);
	var obj2 = {a: "test2", b: true};
	testing(obj2);
}

And Servoy seemed happy about that.

Thanks Patrick. That’s perfect. I’d tried that as well, but I enclosed both the property name and type in the brackets instead of just the name (which Developer did not like). Thank you. You’ve just made my night.

Another question: the following JSDoc causes the hover-over info to stop prematurely:

@param {{tMessage:String, tTo:String, [tSubject]:String, [aAttachments]:Array<Object>, [tFrom]:String, [tCC]:String, [tBCC]:String, [bNotifyIT]:Boolean, [dQueueUntil]:Number}} emailProperties 

I’ve found that it is the “<” in “[aAttachments]:Array”. If I remove the type, I end up with an error checking warning in the place where I call the method. If I change it to specify the properties of the object “[aAttachments]:Array<{tPath:String, [tName]:String}>” I still receive an error check warning, this time saying that I am passing Array, which doesn’t match the definition.

Thoughts?

My thought: yeah, it’s buggy. :)