Class inheritance. Classical inheritance goodness in Javascipt. Create a rich class hierarchy that feels sane, with all the power and common sense you've come to expect in an object-oriented language.
Mixins. Add member functions to a class without enforcing a strict single-inheritance relationships. The
wrapped"advice" decorations can be used to modify existing functions.
interfacepattern lets you write code that is self-documenting and forces define-time checks on code contracts.
Member decorations. Use modifiers on class members, mixin members, or interface members to change their behavior or enforce inheritance and access semantics, or use custom decorations and reflection to amp up your own classes and reduce boilerplate.
Define-time semantics checking. Use the
overridemember decorations to ensure predictable inheritance behavior, and get feedback in the form of define-time errors when implementation contracts are broken.
Install all of the required modules to build and use
grunt to build the files into the
npm install grunt release
Easy peasy. Defining a class involves passing a hash of all the corresponding member functions to the typedef function, as well as (optionally) naming the class.
// Base class definition example ....
It works exactly as you might imagine.
// Base class instantiation and use example ...
Notice that the (optional) constructor function is provided via the
__constructor__ property in the hash.
Classes are constructor functions that leverage the native prototypical inheritance model.
Typedef allows for single-inheritance from a base class via chaining the
.extends() function in your class definition. Child constructors are
implicitly called, from the base up, when instantiating child classes.
// Child class definition example
Child classes can be thought of as inheriting the members of the base class-- though really what is going on is simply building up the native prototype chain.
// Child class use example
Mixins provide a way to add or augment existing member functions in a class. Multiple mixins can be used during a class definition, and the advice decorations allow for modifying existing functions.
Mixins are added after the class is setup, meaning any wrapping augmentations will be applied on top of defined members of the class.
To add a mixin to your class definition, chain the
.uses() method in your
// Mixin definition ...
In addition, using interface patterns allows for your code to be more self-documenting. Any discrepancy between a class and an interface it implements will cause define-time exception, informing you of the issue.
Specify that a class implements a specific interface by chaining the
implements() method in your class definition.
// Interface definition ...
The inheritance decorations are used to govern and check the inheritance semantics of your classes.
All inheritance decorations only add additional checking overhead during define time; no run-time overhead is incurred after the initial load and definition.
virtual decoration follows its classical use, in that indicates a class
member may be overridden in child class. By default, all members are
non-virtual, and thus cannot be overridden. This effectively makes any sort of
member hiding in Typedef explicit.
Attempting to override a base member that isn't virtual will result in a define-time error.
abstract member is the same as a
virtual member, with the difference
that a derived class must override the abstract member.
A class with at least one abstract member is considered an abstract class. An exception is thrown when attempting to instantiate an abstract class.
override decoration is required when overriding a base member in a child
class. The base member must be
new decoration indicates that the previous implementation of a member is
to be disregarded. This can be used to explicitly hide a base class member that
isn't set to
virtual, for example.
sealed member indicates that it cannot be override at all, even if using
new decoration. This provides a way to very clearly indicate that a
member should not be changed in derived implementations of a class.
Attempting to override a
sealed member will result in a define-time
readonly decoration will define the property with the
flag set to
false. Any attempts to update a
readonly property will silently
fail (unless you
Note that this only applies for the values of members; if a member set as
readonly is initialized with an object, that object can still be mutated.
This decoration allows you to signal in your public API that method is designed
to returned the
this pointer. This allows for the elegant "fluent API" style
of method chaining.
The define-time check uses
function#toString to check all return statements
to ensure that they are returning
this. Returning something else (or not
return statements) will result in a define-time warning.
Typedef makes liberal use of ES5 features such as
Object.create, and thus will work with any modern browser:
- Chrome 7+
- Firefox 4+
- Safari 5.1+
- Opera 4+
- Internet Explorer 9+
Testing is powered by QUnit and can be run from the
command line via
grunt-contrib-qunit. To install all modules and test:
npm install grunt test
Copyright 2013 Brandon Valosek
Typedef is released under the MIT licenses.