typedinterface
v0.1.0
Published
TypedInterface allows you to define the parameter types and return type that a function or method must accept.
Downloads
3
Maintainers
Readme
TypedInterface
TypedInterface allows you to define the parameter types and return type that a function or method must accept.
Usage
defineFunction
Used for wrapping functions within a given context. You can pass in the local context this
or even window
for globals.
Arguments
ctx
the context (or environment, or namespace) where the function is defined.name
the name of the functionargTypes
ordered array of types that the function must acceptrType
The return value type
Example
Interface.defineFunction(this, 'renderTasks', [Array], String);
function renderTasks(tasks) {
return "Tasks: " + tasks.join(", ");
}
try {
renderTasks(1, 2);
} catch (e) {
console.error(e.toString());
// TypeError: Mismatched argument lengths: got 2, wanted 1
}
defineMethod
Used for wrapping methods of a prototype. This allows you to define the types for each method of the prototype, and then use the extend
method to adopt the same definitions for each instance of that prototype. Check out the example for a better explanation.
Arguments
cls
the class/prototype referencename
the name of the methodargTypes
ordered array of types that the function must acceptrType
The return value type
Example
// Define our Interface prototype that various other 'classes' will implement
var ServiceClass = function(){};
ServiceClass.prototype.login = function() {}; // no need to actually write logic here
ServiceClass.prototype.getInputFields = function() {};
Interface.defineMethod(ServiceClass,
"login", [optional(Object), optional(Function)], undefined);
Interface.defineMethod(ServiceClass,
"getInputFields", [Object, String, Function], undefined);
// Example of a class that implements the above defined methods
var SomeService = function(){};
SomeService.prototype.login = function(data, cb) {
[...]
};
SomeService.prototype.getInputFields = function(data, site, cb) {
[...]
};
// Extend it! This will adopt the same type checks as the ServiceClass.
// Any method that SomeService does not implement will fallback to ServiceClass.
// This does not create new wrappers, rather relies on the CACHED wrappers
// for ServiceClass.
SomeService = Interface.extend(ServiceClass, SomeService);
// And instantiate as you normally would:
var SomeServiceInstance = new SomeService();
Exception Examples
var myTasks = [
'Goto park',
'Bake bread',
'Win lottery'
];
var renders = {
tasks: function(tasks) {
return "Tasks: " + tasks.join(", ");
},
badTasks: function(tasks) {
return tasks;
}
};
Interface.defineFunction(renders, 'tasks', [Array], String);
Interface.defineFunction(renders, 'badTasks', [Array], String);
try {
renders.tasks(true);
} catch (e) {
console.error(e.toString());
// TypeError: Mismatched argument 1: got boolean, wanted function Array() { [native code] } for undefined()
}
try {
renders.tasks(myTasks, true);
} catch (e) {
console.error(e.toString());
// TypeError: Mismatched argument lengths: got 2, wanted 1
}
try {
renders.tasks();
} catch (e) {
console.error(e.toString());
// TypeError: Mismatched argument lengths: got 0, wanted 1
}
try {
renders.badTasks(myTasks);
} catch (e) {
console.error(e.toString());
// Mismatched return value (got: object, wanted: function String() { [native code] })
}
// yay!
var out = renders.tasks(myTasks);
console.debug(out);
Credits
The original idea and proof was the work of the rather illustrious Lewis Zimmerman.