TypeScript Type System: Interface Types

In JavaScript, it is common to add more members to existing objects by monkey patching. For example, jQuery UI provides its API by adding a bunch of members to the jQuery object provided by jQuery.

Interface types in conventional programming languages such as Java and C# can’t represent this idiom because interfaces can’t be modified once they are declared. So if TypeScript uses the same interface types as those languages, it could be a severe limitation to the usability of the language.

Fortunately, the designers of TypeScript language were clever enough to come up with an idea to represent this idiom in a type safe manner. This idea is simply to make interface types open, meaning you can add your own members later by simply writing another interface block with the same name.

For example, Box interface has width and height properties. But you can add scale property later by writing another interface block with scale property.

interface Box {
	width: number;
	height: number;
}

interface Box {
	scale: number;
}

var b1: Box = { width: 200, height: 180, scale: 1.0 };
var b2: Box = { width: 400, height: 360 }; // Error because scale is missing

Let’s get back to the jQuery UI example mentioned above. jQuery library declares JQuery interface initially. Later, jQuery UI also declares JQuery interface and add more members to the interface. TypeScript compiler merges these two interfaces into one JQuery interface with members from both interfaces.

/**
 * The jQuery instance members
 */
interface JQuery {
    /**
     * Register a handler to be called when Ajax requests complete. This is an AjaxEvent.
     *
     * @param handler The function to be invoked.
     */
    ajaxComplete(handler: (event: JQueryEventObject, XMLHttpRequest: XMLHttpRequest, ajaxOptions: any) => any): JQuery;
    // ...
}
interface JQuery {

    accordion(): JQuery;
    accordion(methodName: 'destroy'): void;
    // ...
}

TypeScript expands this idea to a more general concept called Declaration Merging. Refer to TypeScript Handbook for more information on merging modules and merging modules with classes/functions/enums.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s