typescript Wiki Rss Feedhttps://typescript.codeplex.com/typescript Wiki Rss DescriptionNew Comment on "Classes in TypeScript"https://typescript.codeplex.com/wikipage?title=Classes in TypeScript&ANCHOR#C31354After catching on how the concept of classes in JavaScript is fundamentally different from how classes are handled in more familiar language the discussion here should start with a strong caveat on what classes are in JS. David Crockfords&#39; JavaScript&#59; The Good Parts and Kyle SImpsons &#34;This &#38; Object Prototypes&#34; are essential reading.BobFrankstonWed, 18 Feb 2015 04:55:54 GMTNew Comment on "Classes in TypeScript" 20150218045554ANew Comment on "Modules in TypeScript"https://typescript.codeplex.com/wikipage?title=Modules in TypeScript&ANCHOR#C31121Typo&#58; The example is correct &#40;--module&#41;, but the prose is wrong &#40;--target&#41;.&#10;-------------&#10;&#10;To compile, we must specify a module target on the command line. For node.js, use --target commonjs&#59; for require.js, use --target amd. For example&#58;&#10;&#10;tsc --module commonjs Test.tsAdamFreidinThu, 04 Dec 2014 17:18:19 GMTNew Comment on "Modules in TypeScript" 20141204051819PUpdated Wiki: Classes in TypeScripthttps://typescript.codeplex.com/wikipage?title=Classes in TypeScript&version=13<div class="wikidoc"><i><b>Please note:</b> This page is a work-in-progress. It may have errors and is subject to change.</i><br />
<hr />
<h1>Introduction</h1>
Traditional JavaScript focuses on functions and prototype-based inheritance as the basic means of building up reusable components, but this may feel a bit awkward to programmers more comfortable with an object-oriented approach, where classes inherit functionality and objects are built from these classes. Starting with ECMAScript 6, the next version of JavaScript, JavaScript programmers will be able to build their applications using this object-oriented class-based approach. In TypeScript, we allow developers to use these techniques now, and compile them down to JavaScript that works across all major browsers and platforms, without having to wait for the next version of JavaScript.<br />
<h1>Classes</h1>
Let&#39;s take a look at a simple class-based example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Greeter {
greeting: string;
constructor(message: string) {
<span style="color:Blue;">this</span>.greeting = message;
}
greet() {
<span style="color:Blue;">return</span> <span style="color:#A31515;">&quot;Hello, &quot;</span> + <span style="color:Blue;">this</span>.greeting;
}
}
<span style="color:Blue;">var</span> greeter = <span style="color:Blue;">new</span> Greeter(<span style="color:#A31515;">&quot;world&quot;</span>);
</pre></div><br />The syntax should look very familiar if you&#39;ve used C# or Java before. We declare a new class &#39;Greeter&#39;. This class has three members, a property called &#39;greeting&#39;, a constructor, and a method &#39;greet&#39;. <br /><br />You&#39;ll notice that in the class when we refer to one of the members of the class we prepend &#39;this.&#39;. This denotes that it&#39;s a member access.<br /><br />In the last line we construct an instance of the Greeter class using &#39;new&#39;. This calls into the constructor we defined earlier, creating a new object with the Greeter shape, and running the constructor to initialize it.<br />
<h1>Inheritance</h1>
In TypeScript, we can use common object-oriented patterns. Of course, one of the most fundamental patterns in class-based programming is being able to extend existing classes to create new ones using inheritance.<br /><br />Let&#39;s take a look at an example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Animal {
name:string;
constructor(theName: string) { <span style="color:Blue;">this</span>.name = theName; }
move(meters: number = 0) {
alert(<span style="color:Blue;">this</span>.name + <span style="color:#A31515;">&quot; moved &quot;</span> + meters + <span style="color:#A31515;">&quot;m.&quot;</span>);
}
}
<span style="color:Blue;">class</span> Snake <span style="color:Blue;">extends</span> Animal {
constructor(name: string) { <span style="color:Blue;">super</span>(name); }
move(meters = 5) {
alert(<span style="color:#A31515;">&quot;Slithering...&quot;</span>);
<span style="color:Blue;">super</span>.move(meters);
}
}
<span style="color:Blue;">class</span> Horse <span style="color:Blue;">extends</span> Animal {
constructor(name: string) { <span style="color:Blue;">super</span>(name); }
move(meters = 45) {
alert(<span style="color:#A31515;">&quot;Galloping...&quot;</span>);
<span style="color:Blue;">super</span>.move(meters);
}
}
<span style="color:Blue;">var</span> sam = <span style="color:Blue;">new</span> Snake(<span style="color:#A31515;">&quot;Sammy the Python&quot;</span>);
<span style="color:Blue;">var</span> tom: Animal = <span style="color:Blue;">new</span> Horse(<span style="color:#A31515;">&quot;Tommy the Palomino&quot;</span>);
sam.move();
tom.move(34);
</pre></div><br />This example covers quite a bit of the inheritance features in TypeScript that are common to other languages. Here we see using the &#39;extends&#39; keywords to create a subclass. You can see this where &#39;Horse&#39; and &#39;Snake&#39; subclass the base class &#39;Animal&#39; and gain access to its features.<br /><br />The example also shows off being able to override methods in the base class with methods that are specialized for the subclass. Here both &#39;Snake&#39; and &#39;Horse&#39; create a &#39;move&#39; method that overrides the &#39;move&#39; from &#39;Animal&#39;, giving it functionality specific to each class.<br />
<h1>Private/Public modifiers</h1>
<h2>Public by default</h2>
You may have noticed in the above examples we haven&#39;t had to use the word &#39;public&#39; to make any of the members of the class visible. Languages like C# require that each member be explicitly labelled &#39;public&#39; to be visible. In TypeScript, each member is public by default. <br /><br />You may still mark members a private, so you control what is publicly visible outside of your class. We could have written the &#39;Animal&#39; class from the previous section like so:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Animal {
<span style="color:Blue;">private</span> name:string;
constructor(theName: string) { <span style="color:Blue;">this</span>.name = theName; }
move(meters: number) {
alert(<span style="color:Blue;">this</span>.name + <span style="color:#A31515;">&quot; moved &quot;</span> + meters + <span style="color:#A31515;">&quot;m.&quot;</span>);
}
}
</pre></div>
<h2>Understanding private</h2>
TypeScript is a structural type system. When we compare two different types, regardless of where they came from, if the types of each member are compatible, then we say the types themselves are compatible. <br /><br />When comparing types that have &#39;private&#39; members, we treat these differently. For two types to be considered compatible, if one of them has a private member, then the other must have a private member that originated in the same declaration. <br /><br />Let&#39;s look at an example to better see how this plays out in practice:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Animal {
<span style="color:Blue;">private</span> name:string;
constructor(theName: string) { <span style="color:Blue;">this</span>.name = theName; }
}
<span style="color:Blue;">class</span> Rhino <span style="color:Blue;">extends</span> Animal {
constructor() { <span style="color:Blue;">super</span>(<span style="color:#A31515;">&quot;Rhino&quot;</span>); }
}
<span style="color:Blue;">class</span> Employee {
<span style="color:Blue;">private</span> name:string;
constructor(theName: string) { <span style="color:Blue;">this</span>.name = theName; }
}
<span style="color:Blue;">var</span> animal = <span style="color:Blue;">new</span> Animal(<span style="color:#A31515;">&quot;Goat&quot;</span>);
<span style="color:Blue;">var</span> rhino = <span style="color:Blue;">new</span> Rhino();
<span style="color:Blue;">var</span> employee = <span style="color:Blue;">new</span> Employee(<span style="color:#A31515;">&quot;Bob&quot;</span>);
animal = rhino;
animal = employee; <span style="color:Green;">//error: Animal and Employee are not compatible</span>
</pre></div><br />In this example, we have an &#39;Animal&#39; and a &#39;Rhino&#39;, with &#39;Rhino&#39; being a subclass of &#39;Animal&#39;. We also have a new class &#39;Employee&#39; that looks identical to &#39;Animal&#39; in terms of shape. We create some instances of these classes and then try to assign them to each other to see what will happen. Because &#39;Animal&#39; and &#39;Rhino&#39; share the private side of their shape from the same declaration of &#39;private name: string&#39; in &#39;Animal&#39;, they are compatible. However, this is not the case for &#39;Employee&#39;. When we try to assign from an &#39;Employee&#39; to &#39;Animal&#39; we get an error that these types are not compatible. Even though &#39;Employee&#39; also has a private member called &#39;name&#39;, it is not the same one as the one created in &#39;Animal&#39;. <br />
<h2>Parameter properties</h2>
The keywords &#39;public&#39; and &#39;private&#39; also give you a shorthand for creating and initializing members of your class, by creating parameter properties. The properties let you can create and initialize a member in one step. Here&#39;s a further revision of the previous example. Notice how we drop &#39;theName&#39; altogether and just use the shortened &#39;private name: string&#39; parameter on the constructor to create and initialize the &#39;name&#39; member.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Animal {
constructor(<span style="color:Blue;">private</span> name: string) { }
move(meters: number) {
alert(<span style="color:Blue;">this</span>.name + <span style="color:#A31515;">&quot; moved &quot;</span> + meters + <span style="color:#A31515;">&quot;m.&quot;</span>);
}
}
</pre></div><br />Using &#39;private&#39; in this way creates and initializes a private member, and similarly for &#39;public&#39;. <br />
<h1>Accessors</h1>
TypeScript supports getters/setters as a way of intercepting accesses to a member of an object. This gives you a way of having finer-grained control over how a member is accessed on each object.<br /><br />Let&#39;s convert a simple class to use &#39;get&#39; and &#39;set&#39;. First, let&#39;s start with an example without getters and setters.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Employee {
fullName: string;
}
<span style="color:Blue;">var</span> employee = <span style="color:Blue;">new</span> Employee();
employee.fullName = <span style="color:#A31515;">&quot;Bob Smith&quot;</span>;
<span style="color:Blue;">if</span> (employee.fullName) {
alert(employee.fullName);
}
</pre></div><br />While allowing people to randomly set fullName directly is pretty handy, this might get us in trouble if we people can change names on a whim. <br /><br />In this version, we check to make sure the user has a secret passcode available before we allow them to modify the employee. We do this by replacing the direct access to fullName with a &#39;set&#39; that will check the passcode. We add a corresponding &#39;get&#39; to allow the previous example to continue to work seamlessly.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> passcode = <span style="color:#A31515;">&quot;secret passcode&quot;</span>;
<span style="color:Blue;">class</span> Employee {
<span style="color:Blue;">private</span> _fullName: string;
get fullName(): string {
<span style="color:Blue;">return</span> <span style="color:Blue;">this</span>._fullName;
}
set fullName(newName: string) {
<span style="color:Blue;">if</span> (passcode &amp;&amp; passcode == <span style="color:#A31515;">&quot;secret passcode&quot;</span>) {
<span style="color:Blue;">this</span>._fullName = newName;
}
<span style="color:Blue;">else</span> {
alert(<span style="color:#A31515;">&quot;Error: Unauthorized update of employee!&quot;</span>);
}
}
}
<span style="color:Blue;">var</span> employee = <span style="color:Blue;">new</span> Employee();
employee.fullName = <span style="color:#A31515;">&quot;Bob Smith&quot;</span>;
<span style="color:Blue;">if</span> (employee.fullName) {
alert(employee.fullName);
}
</pre></div><br />To prove to ourselves that our accessor is now checking the passcode, we can modify the passcode and see that when it doesn&#39;t match we instead get the alert box warning us we don&#39;t have access to update the employee.<br /><br />Note: Accessors require you to set the compiler to output ECMAScript 5.<br />
<h1>Static Properties</h1>
Up to this point, we&#39;ve only talked about the <i>instance</i> members of the class, those that show up on the object when its instantiated. We can also create <i>static</i> members of a class, those that are visible on the class itself rather than on the instances. In this example, we use &#39;static&#39; on the origin, as it&#39;s a general value for all grids. Each instance accesses this value through prepending the name of the class. Similarly to prepending &#39;this.&#39; in front of instance accesses, here we prepend &#39;Grid.&#39; in front of static accesses.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Grid {
<span style="color:Blue;">static</span> origin = {x: 0, y: 0};
calculateDistanceFromOrigin(point: {x: number; y: number;}) {
<span style="color:Blue;">var</span> xDist = (point.x - Grid.origin.x);
<span style="color:Blue;">var</span> yDist = (point.y - Grid.origin.y);
<span style="color:Blue;">return</span> Math.sqrt(xDist * xDist + yDist * yDist) / <span style="color:Blue;">this</span>.scale;
}
constructor (<span style="color:Blue;">public</span> scale: number) { }
}
<span style="color:Blue;">var</span> grid1 = <span style="color:Blue;">new</span> Grid(1.0); <span style="color:Green;">// 1x scale</span>
<span style="color:Blue;">var</span> grid2 = <span style="color:Blue;">new</span> Grid(5.0); <span style="color:Green;">// 5x scale</span>
alert(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
alert(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
</pre></div>
<h1>Advanced Techniques</h1>
<h2>Constructor functions</h2>
When you declare a class in TypeScript, you are actually creating multiple declarations at the same time. The first is the type of the <i>instance</i> of the class.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Greeter {
greeting: string;
constructor(message: string) {
<span style="color:Blue;">this</span>.greeting = message;
}
greet() {
<span style="color:Blue;">return</span> <span style="color:#A31515;">&quot;Hello, &quot;</span> + <span style="color:Blue;">this</span>.greeting;
}
}
<span style="color:Blue;">var</span> greeter: Greeter;
greeter = <span style="color:Blue;">new</span> Greeter(<span style="color:#A31515;">&quot;world&quot;</span>);
alert(greeter.greet());
</pre></div><br />Here, when we say &#39;var greeter: Greeter&#39;, we&#39;re using Greeter as the type of instances of the class Greeter. This is almost second nature to programmers from other object-oriented languages. <br /> <br />We&#39;re also creating another value that we call the <i>constructor function</i>. This is the function that is called when we &#39;new&#39; up instances of the class. To see what this looks like in practice, let&#39;s take a look at the JavaScript created by the above example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> Greeter = (<span style="color:Blue;">function</span> () {
<span style="color:Blue;">function</span> Greeter(message) {
<span style="color:Blue;">this</span>.greeting = message;
}
Greeter.prototype.greet = <span style="color:Blue;">function</span> () {
<span style="color:Blue;">return</span> <span style="color:#A31515;">&quot;Hello, &quot;</span> + <span style="color:Blue;">this</span>.greeting;
};
<span style="color:Blue;">return</span> Greeter;
})();
<span style="color:Blue;">var</span> greeter;
greeter = <span style="color:Blue;">new</span> Greeter(<span style="color:#A31515;">&quot;world&quot;</span>);
alert(greeter.greet());
</pre></div><br />Here, &#39;var Greeter&#39; is going to be assigned the constructor function. When we call &#39;new&#39; and run this function, we get an instance of the class. The constructor function also contains all of the static members of the class. Another way to think of each class is that there is an <i>instance</i> side and a <i>static</i> side.<br /><br />Let&#39;s modify the example a bit to show this difference:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Greeter {
<span style="color:Blue;">static</span> standardGreeting = <span style="color:#A31515;">&quot;Hello, there&quot;</span>;
greeting: string;
greet() {
<span style="color:Blue;">if</span> (<span style="color:Blue;">this</span>.greeting) {
<span style="color:Blue;">return</span> <span style="color:#A31515;">&quot;Hello, &quot;</span> + <span style="color:Blue;">this</span>.greeting;
}
<span style="color:Blue;">else</span> {
<span style="color:Blue;">return</span> Greeter.standardGreeting;
}
}
}
<span style="color:Blue;">var</span> greeter1: Greeter;
greeter1 = <span style="color:Blue;">new</span> Greeter();
alert(greeter1.greet());
<span style="color:Blue;">var</span> greeterMaker: <span style="color:Blue;">typeof</span> Greeter = Greeter;
greeterMaker.standardGreeting = <span style="color:#A31515;">&quot;Hey there!&quot;</span>;
<span style="color:Blue;">var</span> greeter2:Greeter = <span style="color:Blue;">new</span> greeterMaker();
alert(greeter2.greet());
</pre></div><br />In this example, &#39;greeter1&#39; works similarly to before. We instantiate the &#39;Greeter&#39; class, and use this object. This we have seen before.<br /><br />Next, we then use the class directly. Here we create a new variable called &#39;greeterMaker&#39;. This variable will hold the class itself, or said another way its constructor function. Here we use &#39;typeof Greeter&#39;, that is &quot;give me the type of the Greeter class itself&quot; rather than the instance type. Or, more precisely, &quot;give me the type of the symbol called Greeter&quot;, which is the type of the constructor function. This type will contain all of the static members of Greeter along with the constructor that creates instances of the Greeter class. We show this by using &#39;new&#39; on &#39;greeterMaker&#39;, creating new instances of &#39;Greeter&#39; and invoking them as before.<br />
<h2>Using a class as an interface</h2>
As we said in the previous section, a class declaration creates two things: a type representing instances of the class and a constructor function. Because classes create types, you can use them in the same places you would be able to use interfaces.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Point {
x: number;
y: number;
}
<span style="color:Blue;">interface</span> Point3d <span style="color:Blue;">extends</span> Point {
z: number;
}
<span style="color:Blue;">var</span> point3d: Point3d = {x: 1, y: 2, z: 3};
</pre></div><br /></div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 17:10:27 GMTUpdated Wiki: Classes in TypeScript 20141103051027PUpdated Wiki: Generics in TypeScripthttps://typescript.codeplex.com/wikipage?title=Generics in TypeScript&version=8<div class="wikidoc"><i><b>Please note:</b> This page is a work-in-progress. It may have errors and is subject to change.</i><br />
<hr />
<h1>Introduction</h1>
A major part of software engineering is building components that not only have well-defined and consistent APIs, but are also reusable. Components that are capable of working on the data of today as well as the data of tomorrow will give you the most flexible capabilities for building up large software systems.<br /><br />In languages like C# and Java, one of the main tools in the toolbox for creating reusable components is &#39;generics&#39;, that is, being able to create a component that can work over a variety of types rather than a single one. This allows users to consume these components and use their own types.<br />
<h1>Hello World of Generics</h1>
To start off, let&#39;s do the &quot;hello world&quot; of generics: the identity function. The identity function is a function that will return back whatever is passed in. You can think of this in a similar way to the &#39;echo&#39; command. <br /><br />Without generics, we would either have to give the identity function a specific type:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity(arg: number): number {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />Or, we could describe the identity function using the &#39;any&#39; type:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity(arg: any): any {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />While using &#39;any&#39; is certainly generic in that will accept any and all types for the type of &#39;arg&#39;, we actually are losing the information about what that type was when the function returns. If we passed in a number, the only information we have is that any type could be returned. <br /><br />Instead, we need a way of capturing the type of the argument in such a way that we can also use it to denote what is being returned. Here, we will use a <i>type variable</i>, a special kind of variable that works on types rather than values. <br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />We&#39;ve now added a type variable &#39;T&#39; to the identity function. This &#39;T&#39; allows us to capture the type the user provides (eg, number), so that we can use that information later. Here, we use &#39;T&#39; again as the return type. On inspection, we can now see the same type is used for the argument and the return type. This allows us to traffic that type information in one side of the function and out the other.<br /><br />We say that this version of the &#39;identity&#39; function is generic, as it works over a range of types. Unlike using &#39;any&#39;, it&#39;s also just as precise (ie, it doesn&#39;t lose any information) as the first &#39;identity&#39; function that used numbers for the argument and return type.<br /><br />Once we&#39;ve written the generic identity function, we can call it in one of two ways. The first way is to pass all of the arguments, including the type argument, to the function:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> output = identity&lt;string&gt;(<span style="color:#A31515;">&quot;myString&quot;</span>); <span style="color:Green;">// type of output will be &#39;string&#39;</span>
</pre></div><br />Here we explicitly set &#39;T&#39; to be string as one of the arguments to the function call, denoted using the &lt;&gt; around the arguments rather than ().<br /><br />The second way is also perhaps the most common. Here we use /type argument inference/, that is, we want the compiler to set the value of T for us automatically based on the type of the argument we pass in:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> output = identity(<span style="color:#A31515;">&quot;myString&quot;</span>); <span style="color:Green;">// type of output will be &#39;string&#39;</span>
</pre></div><br />Notice that we didn&#39;t have explicitly pass the type in the angle brackets (&lt;&gt;), the compiler just looked at the value &quot;myString&quot;, and set T to its type. While type argument inference can be a helpful tool to keep code shorter and more readable, you may need to explicitly pass in the type arguments as we did in the previous example when the compiler fails to infer the type, as may happen in more complex examples.<br />
<h1>Working with Generic Type Variables</h1>
When you begin to use generics, you&#39;ll notice that when you create generic functions like &#39;identity&#39;, the compiler will enforce that you use any generically typed parameters in the body of the function correctly. That is, that you actually treat these parameters as if they could be any and all types.<br /><br />Let&#39;s take our &#39;identity&#39; function from earlier:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />What if want to also log the length of the argument &#39;arg&#39; to the console with each call. We might be tempted to write this:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: T): T {
console.log(arg.length); <span style="color:Green;">// Error: T doesn&#39;t have .length</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />When we do, the compiler will give us an error that we&#39;re using the &quot;.length&quot; member of &#39;arg&#39;, but nowhere have we said that &#39;arg&#39; has this member. Remember, we said earlier that these type variables stand in for any and all types, so someone using this function could have passed in a &#39;number&#39; instead, which does not have a &quot;.length&quot; member. <br /><br />Let&#39;s say that we&#39;ve actually intended this function to work on arrays of T rather that T directly. Since we&#39;re working with arrays, the .length member should be available. We can describe this just like we would create arrays of other types:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: T[]): T[] {
console.log(arg.length); <span style="color:Green;">// Array has a .length, so no more error</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />You can read the type of logging Identity as &quot;the generic function loggingIdentity, takes a type parameter T, and an argument &#39;arg&#39; which is an array of these T&#39;s, and returns an array of T&#39;s. If we passed in an array of numbers, we&#39;d get an array of numbers back out, as T would bind to number. This allows us to use our generic type variable &#39;T&#39; as part of the types we&#39;re working with, rather than the whole type, giving us greater flexibility. <br /><br />We can alternatively write the sample example this way:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: Array&lt;T&gt;): Array&lt;T&gt; {
console.log(arg.length); <span style="color:Green;">// Array has a .length, so no more error</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />You may already be familiar with this style of type from other languages. In the next section, we&#39;ll cover how you can create your own generic types like Array&lt;T&gt;.<br />
<h1>Generic Types</h1>
In previous sections, we created generic identity functions that worked over a range of types. In this section, we&#39;ll explore the type of the functions themselves and how to create generic interfaces.<br /><br />The type of generic functions is just like those of non-generic functions, with the type parameters listed first, similarly to function declarations:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: &lt;T&gt;(arg: T)=&gt;T = identity;
</pre></div><br />We could also have used a different name for the generic type parameter in the type, so long as the number of type variables and how the type variables are used line up.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: &lt;U&gt;(arg: U)=&gt;U = identity;
</pre></div><br />We can also write the generic type as a call signature of an object literal type:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: {&lt;T&gt;(arg: T): T} = identity;
</pre></div><br />Which leads us to writing our first generic interface. Let&#39;s take the object literal from the previous example and move it to an interface:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> GenericIdentityFn {
&lt;T&gt;(arg: T): T;
}
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: GenericIdentityFn = identity;
</pre></div><br />In a similar example, we may want to move the generic parameter to be a parameter of the whole interface. This lets us see what type(s) we&#39;re generic over (eg Dictionary&lt;string&gt; rather than just Dictionary). This makes the type parameter visible to all the other members of the interface. <br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> GenericIdentityFn&lt;T&gt; {
(arg: T): T;
}
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: GenericIdentityFn&lt;number&gt; = identity;
</pre></div><br />Notice that our example has changed to be something slightly different. Instead of describing a generic function, we now have a non-generic function signature that is a part of a generic type. When we use GenericIdentityFn, we now will also need to specify the corresponding type argument (here: number), effectively locking in what the underlying call signature will use. Understanding when to put the type parameter directly on the call signature and when to put it on the interface itself will be helpful in describing what aspects of a type are generic.<br /><br />In addition to generic interfaces, we can also create generic classes. Note that it is not possible to create generic enums and modules.<br />
<h1>Generic Classes</h1>
A generic class has a similar shape to a generic interface. Generic classes have a generic type parameter list in angle brackets (&lt;&gt;) following the name of the class.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> GenericNumber&lt;T&gt; {
zeroValue: T;
add: (x: T, y: T) =&gt; T;
}
<span style="color:Blue;">var</span> myGenericNumber = <span style="color:Blue;">new</span> GenericNumber&lt;number&gt;();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = <span style="color:Blue;">function</span>(x, y) { <span style="color:Blue;">return</span> x + y; };
</pre></div><br />This is a pretty literal use of the &#39;GenericNumber&#39; class, but you may have noticed that nothing is restricting is to only use the &#39;number&#39; type. We could have instead used &#39;string&#39; or even more complex objects.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> stringNumeric = <span style="color:Blue;">new</span> GenericNumber&lt;string&gt;();
stringNumeric.zeroValue = <span style="color:#A31515;">&quot;&quot;</span>;
stringNumeric.add = <span style="color:Blue;">function</span>(x, y) { <span style="color:Blue;">return</span> x + y; };
alert(stringNumeric.add(stringNumeric.zeroValue, <span style="color:#A31515;">&quot;test&quot;</span>));
</pre></div><br />Just as with interface, putting the type parameter on the class itself lets us make sure all of the properties of the class are working with the same type.<br /><br />As we covered in <a href="https://typescript.codeplex.com/wikipage?title=Classes%20in%20TypeScript&referringTitle=Generics%20in%20TypeScript">Classes</a>, a class has two side to its type: the static side and the instance side. Generic classes are only generic over their instance side rather than their static side, so when working with classes, static members can not use the class&#39;s type parameter.<br />
<h1>Generic Constraints</h1>
If you remember from an earlier example, you may sometimes want to write a generic function that works on a set of types where you have some knowledge about what capabilities that set of types will have. In our &#39;loggingIdentity&#39; example, we wanted to be able access the &quot;.length&quot; property of &#39;arg&#39;, but the compiler could not prove that every type had a &quot;.length&quot; property, so it warns us that we can&#39;t make this assumption.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: T): T {
console.log(arg.length); <span style="color:Green;">// Error: T doesn&#39;t have .length</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />Instead of working with any and all types, we&#39;d like to constrain this function to work with any and all types that also have the &quot;.length&quot; property. As long as the type has this member, we&#39;ll allow it, but it&#39;s required to have at least this member. To do so, we must list our requirement as a constraint on what T can be.<br /><br />To do so, we&#39;ll create an interface that describes our constraint. Here, we&#39;ll create an interface that has a single &quot;.length&quot; property and then we&#39;ll use this interface and the <span class="codeInline">extends</span> keyword to denote our constraint:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Lengthwise {
length: number;
}
<span style="color:Blue;">function</span> loggingIdentity&lt;T <span style="color:Blue;">extends</span> Lengthwise&gt;(arg: T): T {
console.log(arg.length); <span style="color:Green;">// Now we know it has a .length property, so no more error</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />Because the generic function is now constrained, it will no longer work over any and all types:<br /><br /><div style="color:Black;background-color:White;"><pre>
loggingIdentity(3); <span style="color:Green;">// Error, number doesn&#39;t have a .length property</span>
</pre></div><br />Instead, we need to pass in values whose type has all the required properties:<br /><br /><div style="color:Black;background-color:White;"><pre>
loggingIdentity({length: 10, value: 3});
</pre></div>
<h2>Using Type Parameters in Generic Constraints</h2>
In some cases, it may be useful to declare a type parameter that is constrained by another type parameter. For example,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> find&lt;T, U <span style="color:Blue;">extends</span> Findable&lt;T&gt;&gt;(n: T, s: U) { <span style="color:Green;">// errors because type parameter used in constraint</span>
<span style="color:Green;">// ...</span>
}
find (giraffe, myAnimals);
</pre></div><br />You can achieve the pattern above by replacing the type parameter with its constraint. Rewriting the example above,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> find&lt;T&gt;(n: T, s: Findable&lt;T&gt;) {
<span style="color:Green;">// ...</span>
}
find(giraffe, myAnimals);
</pre></div><br /><i>Note:</i> The above is not strictly identical, as the return type of the first function could have returned &#39;U&#39;, which the second function pattern does not provide a means to do.<br />
<h2>Using Class Types in Generics</h2>
When creating factories in TypeScript using generics, it is necessary to refer to class types by their constructor functions. For example,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> create&lt;T&gt;(c: {<span style="color:Blue;">new</span>(): T; }): T {
<span style="color:Blue;">return</span> <span style="color:Blue;">new</span> c();
}
</pre></div><br />A more advanced example uses the prototype property to infer and constrain relationships between the constructor function and the instance side of class types.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> BeeKeeper {
hasMask: <span style="color:Blue;">boolean</span>;
}
<span style="color:Blue;">class</span> ZooKeeper {
nametag: string;
}
<span style="color:Blue;">class</span> Animal {
numLegs: number;
}
<span style="color:Blue;">class</span> Bee <span style="color:Blue;">extends</span> Animal {
keeper: BeeKeeper;
}
<span style="color:Blue;">class</span> Lion <span style="color:Blue;">extends</span> Animal {
keeper: ZooKeeper;
}
<span style="color:Blue;">function</span> findKeeper&lt;A <span style="color:Blue;">extends</span> Animal, K&gt; (a: {<span style="color:Blue;">new</span>(): A;
prototype: {keeper: K}}): K {
<span style="color:Blue;">return</span> a.prototype.keeper;
}
findKeeper(Lion).nametag; <span style="color:Green;">// typechecks!</span>
</pre></div></div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 17:00:53 GMTUpdated Wiki: Generics in TypeScript 20141103050053PUpdated Wiki: Writing Definition (.d.ts) Fileshttps://typescript.codeplex.com/wikipage?title=Writing Definition (.d.ts) Files&version=11<div class="wikidoc"><h1>Introduction</h1>
When using an external JavaScript library, or new host API, you&#39;ll need to use a declaration file (.d.ts) to describe the shape of that library. This guide covers a few high-level concepts specific to writing definition files, then proceeds with a number of examples that show how to transcribe various concepts to their matching definition file descriptions.<br />
<h1>Guidelines and Specifics</h1>
<h2>Workflow</h2>
The best way to write a .d.ts file is to start from the documentation of the library, not the code. Working from the documentation ensures the surface you present isn&#39;t muddied with implementation details, and is typically much easier to read than JS code. The examples below will be written as if you were reading documentation that presented example calling code.<br />
<h2>Namespacing</h2>
When defining interfaces (for example, &quot;options&quot; objects), you have a choice about whether to put these types inside a module or not. This is largely a judgement call -- if the consumer is likely to often declare variables or parameters of that type, and the type can be named without risk of colliding with other types, prefer placing it in the global namespace. If the type is not likely to be referenced directly, or can&#39;t be named with a reasonably unique name, do use a module to prevent it from colliding with other types.<br />
<h2>Callbacks</h2>
Many JavaScript libraries take a function as a parameter, then invoke that function later with a known set of arguments. When writing the function signatures for these types, <b>do not</b> mark those parameters as optional. The right way to think of this is <i>&quot;What parameters will be provided?&quot;</i>, not <i>&quot;What parameters will be consumed?&quot;</i>. While TypeScript 0.9.7 and above does not enforce that the optionality, bivariance on argument optionality might be enforced by an external linter.<br />
<h2>Extensibility and Declaration Merging</h2>
When writing definition files, it&#39;s important to remember TypeScript&#39;s rules for extending existing objects. You might have a choice of declaring a variable using an anonymous type or an interface type:<br /><br /><b>Anonymously-typed var</b><br /><br /><div style="color:Black;background-color:White;"><pre>
declare <span style="color:Blue;">var</span> MyPoint: { x: number; y: number; };
</pre></div><br /><b>Interfaced-typed var</b><br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SomePoint { x: number; y: number; }
declare <span style="color:Blue;">var</span> MyPoint: SomePoint;
</pre></div><br />From a consumption side these declarations are identical, but the type <span class="codeInline">SomePoint</span> can be extended through interface merging:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SomePoint { z: number; }
MyPoint.z = 4; <span style="color:Green;">// OK</span>
</pre></div><br />Whether or not you want your declarations to be extensible in this way is a bit of a judgement call. As always, try to represent the intent of the library here.<br />
<h2>Class Decomposition</h2>
Classes in TypeScript create two separate types: the instance type, which defines what members an instance of a class has, and the constructor function type, which defines what members the class constructor function has. The constructor function type is also known as the &quot;static side&quot; type because it includes static members of the class.<br /><br />While you can reference the static side of a class using the <span class="codeInline">typeof</span> keyword, it is sometimes useful or necessary when writing definition files to use the <i>decomposed class</i> pattern which explicitly separates the instance and static types of class.<br /><br />As an example, the following two declarations are nearly equivalent from a consumption perspective:<br /><br /><b>Standard</b><br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> A {
<span style="color:Blue;">static</span> st: string;
inst: number;
constructor(m: any) {}
}
</pre></div><br /><b>Decomposed</b><br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> A_Static {
<span style="color:Blue;">new</span>(m: any): A_Instance;
st: string;
}
<span style="color:Blue;">interface</span> A_Instance {
inst: number;
}
declare <span style="color:Blue;">var</span> A: A_Static;
</pre></div><br />The trade-offs here are as follows:
<ul><li>Standard classes can be inherited from using <span class="codeInline">extends</span>; decomposed classes cannot. This might change in later version of TypeScript if arbitrary <span class="codeInline">extends</span> expressions are allowed.</li>
<li>It is possible to add members later (through declaration merging) to the static side of both standard and decomposed classes</li>
<li>It is possible to add instance members to decomposed classes, but not standard classes</li>
<li>You&#39;ll need to come up with sensible names for more types when writing a decomposed class</li></ul>
<h2>Naming Conventions</h2>
In general, do not prefix interfaces with <span class="codeInline">I</span> (e.g. <span class="codeInline">IColor</span>). Because the concept of an interface in TypeScript is much more broad than in C# or Java, the <span class="codeInline">IFoo</span> naming convention is not broadly useful.<br />
<h1>Examples</h1>
Let&#39;s jump in to the examples section. For each example, sample <i>usage</i> of the library is provided, followed by the definition code that accurately types the usage. When there are multiple good representations, more than one definition sample might be listed.<br />
<h2>Options Objects</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
animalFactory.create(<span style="color:#A31515;">&quot;dog&quot;</span>);
animalFactory.create(<span style="color:#A31515;">&quot;giraffe&quot;</span>, { name: <span style="color:#A31515;">&quot;ronald&quot;</span> });
animalFactory.create(<span style="color:#A31515;">&quot;panda&quot;</span>, { name: <span style="color:#A31515;">&quot;bob&quot;</span>, height: 400 });
<span style="color:Green;">// Invalid: name must be provided if options is given</span>
animalFactory.create(<span style="color:#A31515;">&quot;cat&quot;</span>, { height: 32 });
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
module animalFactory {
<span style="color:Blue;">interface</span> AnimalOptions {
name: string;
height?: number;
weight?: number;
}
<span style="color:Blue;">function</span> create(name: string, animalOptions?: AnimalOptions): Animal;
}
</pre></div>
<h2>Functions with Properties</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
zooKeeper.workSchedule = <span style="color:#A31515;">&quot;morning&quot;</span>;
zooKeeper(giraffeCage);
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// Note: Function must precede module</span>
<span style="color:Blue;">function</span> zooKeeper(cage: AnimalCage);
module zooKeeper {
<span style="color:Blue;">var</span> workSchedule: string;
}
</pre></div>
<h2>New + callable methods</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> w = widget(32, 16);
<span style="color:Blue;">var</span> y = <span style="color:Blue;">new</span> widget(<span style="color:#A31515;">&quot;sprocket&quot;</span>);
<span style="color:Green;">// w and y are both widgets</span>
w.sprock();
y.sprock();
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Widget {
sprock(): <span style="color:Blue;">void</span>;
}
<span style="color:Blue;">interface</span> WidgetFactory {
<span style="color:Blue;">new</span>(name: string): Widget;
(width: number, height: number): Widget;
}
declare <span style="color:Blue;">var</span> widget: WidgetFactory;
</pre></div>
<h2>Global / External-agnostic Libraries</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// Either</span>
<span style="color:Blue;">import</span> x = require(<span style="color:#A31515;">&#39;zoo&#39;</span>);
x.open();
<span style="color:Green;">// or</span>
zoo.open();
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
module zoo {
<span style="color:Blue;">function</span> open(): <span style="color:Blue;">void</span>;
}
declare module <span style="color:#A31515;">&quot;zoo&quot;</span> {
<span style="color:Blue;">export</span> = zoo;
}
</pre></div>
<h2>Single Complex Object in External Modules</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// Super-chainable library for eagles</span>
<span style="color:Blue;">import</span> eagle = require(<span style="color:#A31515;">&#39;./eagle&#39;</span>);
<span style="color:Green;">// Call directly</span>
eagle(<span style="color:#A31515;">&#39;bald&#39;</span>).fly();
<span style="color:Green;">// Invoke with new</span>
<span style="color:Blue;">var</span> eddie = <span style="color:Blue;">new</span> eagle(1000);
<span style="color:Green;">// Set properties</span>
eagle.favorite = <span style="color:#A31515;">&#39;golden&#39;</span>;
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// Note: can use any name here, but has to be the same throughout this file</span>
declare <span style="color:Blue;">function</span> eagle(name: string): eagle;
declare module eagle {
<span style="color:Blue;">var</span> favorite: string;
<span style="color:Blue;">function</span> fly(): <span style="color:Blue;">void</span>;
}
<span style="color:Blue;">interface</span> eagle {
<span style="color:Blue;">new</span>(awesomeness: number): eagle;
}
<span style="color:Blue;">export</span> = eagle;
</pre></div>
<h2>Callbacks</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
addLater(3, 4, (x) =&gt; console.log(<span style="color:#A31515;">&#39;x = &#39;</span> + x));
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// Note: &#39;void&#39; return type is preferred here</span>
<span style="color:Blue;">function</span> addLater(x: number, y: number, (sum: number) =&gt; <span style="color:Blue;">void</span>): <span style="color:Blue;">void</span>;
</pre></div><br />Please post a comment <a href="https://typescript.codeplex.com/wikipage?title=https%3a%2f%2fgithub.com%2fMicrosoft%2fTypeScript%2fissues&referringTitle=Writing%20Definition%20%28.d.ts%29%20Files">here</a> if there&#39;s a pattern you&#39;d like to see documented! We&#39;ll add to this as we can.</div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:44:12 GMTUpdated Wiki: Writing Definition (.d.ts) Files 20141103044412PUpdated Wiki: Writing Definition (.d.ts) Fileshttps://typescript.codeplex.com/wikipage?title=Writing Definition (.d.ts) Files&version=10<div class="wikidoc"><h1>Introduction</h1>
When using an external JavaScript library, or new host API, you&#39;ll need to use a declaration file (.d.ts) to describe the shape of that library. This guide covers a few high-level concepts specific to writing definition files, then proceeds with a number of examples that show how to transcribe various concepts to their matching definition file descriptions.<br />
<h1>Guidelines and Specifics</h1>
<h2>Workflow</h2>
The best way to write a .d.ts file is to start from the documentation of the library, not the code. Working from the documentation ensures the surface you present isn&#39;t muddied with implementation details, and is typically much easier to read than JS code. The examples below will be written as if you were reading documentation that presented example calling code.<br />
<h2>Namespacing</h2>
When defining interfaces (for example, &quot;options&quot; objects), you have a choice about whether to put these types inside a module or not. This is largely a judgement call -- if the consumer is likely to often declare variables or parameters of that type, and the type can be named without risk of colliding with other types, prefer placing it in the global namespace. If the type is not likely to be referenced directly, or can&#39;t be named with a reasonably unique name, do use a module to prevent it from colliding with other types.<br />
<h2>Callbacks</h2>
Many JavaScript libraries take a function as a parameter, then invoke that function later with a known set of arguments. When writing the function signatures for these types, <b>do not</b> mark those parameters as optional. The right way to think of this is <i>&quot;What parameters will be provided?&quot;</i>, not <i>&quot;What parameters will be consumed?&quot;</i>. While TypeScript 0.9.7 and above does not enforce that the optionality, bivariance on argument optionality might be enforced by an external linter.<br />
<h2>Extensibility and Declaration Merging</h2>
When writing definition files, it&#39;s important to remember TypeScript&#39;s rules for extending existing objects. You might have a choice of declaring a variable using an anonymous type or an interface type:<br /><br /><b>Anonymously-typed var</b><br /><br /><div style="color:Black;background-color:White;"><pre>
declare <span style="color:Blue;">var</span> MyPoint: { x: number; y: number; };
</pre></div><br /><b>Interfaced-typed var</b><br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SomePoint { x: number; y: number; }
declare <span style="color:Blue;">var</span> MyPoint: SomePoint;
</pre></div><br />From a consumption side these declarations are identical, but the type <span class="codeInline">SomePoint</span> can be extended through interface merging:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SomePoint { z: number; }
MyPoint.z = 4; <span style="color:Green;">// OK</span>
</pre></div><br />Whether or not you want your declarations to be extensible in this way is a bit of a judgement call. As always, try to represent the intent of the library here.<br />
<h2>Class Decomposition</h2>
Classes in TypeScript create two separate types: the instance type, which defines what members an instance of a class has, and the constructor function type, which defines what members the class constructor function has. The constructor function type is also known as the &quot;static side&quot; type because it includes static members of the class.<br /><br />While you can reference the static side of a class using the <span class="codeInline">typeof</span> keyword, it is sometimes useful or necessary when writing definition files to use the <i>decomposed class</i> pattern which explicitly separates the instance and static types of class.<br /><br />As an example, the following two declarations are nearly equivalent from a consumption perspective:<br /><br /><b>Standard</b><br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> A {
<span style="color:Blue;">static</span> st: string;
inst: number;
constructor(m: any) {}
}
</pre></div><br /><b>Decomposed</b><br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> A_Static {
<span style="color:Blue;">new</span>(m: any): A_Instance;
st: string;
}
<span style="color:Blue;">interface</span> A_Instance {
inst: number;
}
declare <span style="color:Blue;">var</span> A: A_Static;
</pre></div><br />The trade-offs here are as follows:
<ul><li>Standard classes can be inherited from using <span class="codeInline">extends</span>; decomposed classes cannot. This might change in later version of TypeScript if arbitrary <span class="codeInline">extends</span> expressions are allowed.</li>
<li>It is possible to add members later (through declaration merging) to the static side of both standard and decomposed classes</li>
<li>It is possible to add instance members to decomposed classes, but not standard classes</li>
<li>You&#39;ll need to come up with sensible names for more types when writing a decomposed class</li></ul>
<h2>Naming Conventions</h2>
In general, do not prefix interfaces with <span class="codeInline">I</span> (e.g. <span class="codeInline">IColor</span>). Because the concept of an interface in TypeScript is much more broad than in C# or Java, the <span class="codeInline">IFoo</span> naming convention is not broadly useful.<br />
<h1>Examples</h1>
Let&#39;s jump in to the examples section. For each example, sample <i>usage</i> of the library is provided, followed by the definition code that accurately types the usage. When there are multiple good representations, more than one definition sample might be listed.<br />
<h2>Options Objects</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
animalFactory.create(<span style="color:#A31515;">&quot;dog&quot;</span>);
animalFactory.create(<span style="color:#A31515;">&quot;giraffe&quot;</span>, { name: <span style="color:#A31515;">&quot;ronald&quot;</span> });
animalFactory.create(<span style="color:#A31515;">&quot;panda&quot;</span>, { name: <span style="color:#A31515;">&quot;bob&quot;</span>, height: 400 });
<span style="color:Green;">// Invalid: name must be provided if options is given</span>
animalFactory.create(<span style="color:#A31515;">&quot;cat&quot;</span>, { height: 32 });
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
module animalFactory {
<span style="color:Blue;">interface</span> AnimalOptions {
name: string;
height?: number;
weight?: number;
}
<span style="color:Blue;">function</span> create(name: string, animalOptions?: AnimalOptions): Animal;
}
</pre></div>
<h2>Functions with Properties</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
zooKeeper.workSchedule = <span style="color:#A31515;">&quot;morning&quot;</span>;
zooKeeper(giraffeCage);
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// Note: Function must precede module</span>
<span style="color:Blue;">function</span> zooKeeper(cage: AnimalCage);
module zooKeeper {
<span style="color:Blue;">var</span> workSchedule: string;
}
</pre></div>
<h2>New + callable methods</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> w = widget(32, 16);
<span style="color:Blue;">var</span> y = <span style="color:Blue;">new</span> widget(<span style="color:#A31515;">&quot;sprocket&quot;</span>);
<span style="color:Green;">// w and y are both widgets</span>
w.sprock();
y.sprock();
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Widget {
sprock(): <span style="color:Blue;">void</span>;
}
<span style="color:Blue;">interface</span> WidgetFactory {
<span style="color:Blue;">new</span>(name: string): Widget;
(width: number, height: number): Widget;
}
declare <span style="color:Blue;">var</span> widget: WidgetFactory;
</pre></div>
<h2>Global / External-agnostic Libraries</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// Either</span>
<span style="color:Blue;">import</span> x = require(<span style="color:#A31515;">&#39;zoo&#39;</span>);
x.open();
<span style="color:Green;">// or</span>
zoo.open();
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
module zoo {
<span style="color:Blue;">function</span> open(): <span style="color:Blue;">void</span>;
}
declare module <span style="color:#A31515;">&quot;zoo&quot;</span> {
<span style="color:Blue;">export</span> = zoo;
}
</pre></div>
<h2>Single Complex Object in External Modules</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// Super-chainable library for eagles</span>
<span style="color:Blue;">import</span> eagle = require(<span style="color:#A31515;">&#39;./eagle&#39;</span>);
<span style="color:Green;">// Call directly</span>
eagle(<span style="color:#A31515;">&#39;bald&#39;</span>).fly();
<span style="color:Green;">// Invoke with new</span>
<span style="color:Blue;">var</span> eddie = <span style="color:Blue;">new</span> eagle(1000);
<span style="color:Green;">// Set properties</span>
eagle.favorite = <span style="color:#A31515;">&#39;golden&#39;</span>;
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// Note: can use any name here, but has to be the same throughout this file</span>
declare <span style="color:Blue;">function</span> eagle(name: string): eagle;
declare module eagle {
<span style="color:Blue;">var</span> favorite: string;
<span style="color:Blue;">function</span> fly(): <span style="color:Blue;">void</span>;
}
<span style="color:Blue;">interface</span> eagle {
<span style="color:Blue;">new</span>(awesomeness: number): eagle;
}
<span style="color:Blue;">export</span> = eagle;
</pre></div>
<h2>Callbacks</h2>
<b>Usage</b><br /><div style="color:Black;background-color:White;"><pre>
addLater(3, 4, (x) =&gt; console.log(<span style="color:#A31515;">&#39;x = &#39;</span> + x));
</pre></div><br /><b>Typing</b><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// Note: &#39;void&#39; return type is preferred here</span>
<span style="color:Blue;">function</span> addLater(x: number, y: number, (sum: number) =&gt; <span style="color:Blue;">void</span>): <span style="color:Blue;">void</span>;
</pre></div><br />Please post a comment <a href="https://typescript.codeplex.com/wikipage?title=here&referringTitle=Writing%20Definition%20%28.d.ts%29%20Files">https&#58;&#47;&#47;github.com&#47;Microsoft&#47;TypeScript&#47;issues</a> if there&#39;s a pattern you&#39;d like to see documented! We&#39;ll add to this as we can.</div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:43:38 GMTUpdated Wiki: Writing Definition (.d.ts) Files 20141103044338PUpdated Wiki: Type Compatibility in TypeScripthttps://typescript.codeplex.com/wikipage?title=Type Compatibility in TypeScript&version=12<div class="wikidoc"><h1>Introduction</h1>
Type compatibility in TypeScript is based on structural subtyping. Structural typing is a way of relating types based solely on their members. This is in contrast with nominal typing. Consider the following code:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Named {
name: string;
}
<span style="color:Blue;">class</span> Person {
name: string;
}
<span style="color:Blue;">var</span> p: Named;
<span style="color:Green;">// OK, because of structural typing</span>
p = <span style="color:Blue;">new</span> Person();
</pre></div><br />In nominally-typed languages like C# or Java, the equivalent code would be an error because the Person class does not explicitly describe itself as being an implementor of the Named interface.<br /><br />TypeScript’s structural type system was designed based on how JavaScript code is typically written. Because JavaScript widely uses anonymous objects like function expressions and object literals, it’s much more natural to represent the kinds of relationships found in JavaScript libraries with a structural type system instead of a nominal one.<br />
<h2>A Note on Soundness</h2>
TypeScript’s type system allows certain operations that can’t be known at compile-time to be safe. When a type system has this property, it is said to not be “sound”. The places where TypeScript allows unsound behavior were carefully considered, and throughout this document we’ll explain where these happen and the motivating scenarios behind them.<br />
<h1>Starting out</h1>
The basic rule for TypeScript’s structural type system is that x is compatible with y if y has at least the same members as x. For example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Named {
name: string;
}
<span style="color:Blue;">var</span> x: Named;
<span style="color:Green;">// y’s inferred type is { name: string; location: string; }</span>
<span style="color:Blue;">var</span> y = { name: <span style="color:#A31515;">&#39;Alice&#39;</span>, location: <span style="color:#A31515;">&#39;Seattle&#39;</span> };
x = y;
</pre></div><br />To check whether y can be assigned to x, the compiler checks each property of x to find a corresponding compatible property in y. In this case, y must have a member called ‘name’ that is a string. It does, so the assignment is allowed.<br /><br />The same rule for assignment is used when checking function call arguments:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> greet(n: Named) {
alert(<span style="color:#A31515;">&#39;Hello, &#39;</span> + n.name);
}
greet(y); <span style="color:Green;">// OK</span>
</pre></div><br />Note that ‘y’ has an extra ‘location’ property, but this does not create an error. Only members of the target type (‘Named’ in this case) are considered when checking for compatibility.<br /><br />This comparison process proceeds recursively, exploring the type of each member and sub-member.<br />
<h1>Comparing two functions</h1>
While comparing primitive types and object types is relatively straightforward, the question of what kinds of functions should be considered compatible. Let’s start with a basic example of two functions that differ only in their argument lists:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> x = (a: number) =&gt; 0;
<span style="color:Blue;">var</span> y = (b: number, s: string) =&gt; 0;
y = x; <span style="color:Green;">// OK</span>
x = y; <span style="color:Green;">// Error</span>
</pre></div><br />To check if x is assignable to y, we first look at the parameter list. Each parameter in y must have a corresponding parameter in x with a compatible type. Note that the names of the parameters are not considered, only their types. In this case, every parameter of x has a corresponding compatible parameter in y, so the assignment is allowed.<br /><br />The second assignment is an error, because y has a required second parameter that ‘x’ does not have, so the assignment is disallowed.<br /><br />You may be wondering why we allow ‘discarding’ parameters like in the example y = x. The reason is that assignment is allowed is that ignoring extra function parameters is actually quite common in JavaScript. For example, Array#forEach provides three arguments to the callback function: the array element, its index, and the containing array. Nevertheless, it’s very useful to provide a callback that only uses the first argument:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> items = [1, 2, 3];
<span style="color:Green;">// Don&#39;t force these extra arguments</span>
items.forEach((item, index, array) =&gt; console.log(item));
<span style="color:Green;">// Should be OK!</span>
items.forEach((item) =&gt; console.log(item));
</pre></div><br />Now let’s look at how return types are treated, using two functions that differ only by their return type:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> x = () =&gt; ({name: <span style="color:#A31515;">&#39;Alice&#39;</span>});
<span style="color:Blue;">var</span> y = () =&gt; ({name: <span style="color:#A31515;">&#39;Alice&#39;</span>, location: <span style="color:#A31515;">&#39;Seattle&#39;</span>});
x = y; <span style="color:Green;">// OK</span>
y = x; <span style="color:Green;">// Error because x() lacks a location property</span>
</pre></div><br />The type system enforces that the source function’s return type be a subtype of the target type’s return type.<br />
<h2>Function Argument Bivariance</h2>
When comparing the types of function parameters, assignment succeeds if either the source parameter is assignable to the target parameter, or vice versa. This is unsound because a caller might end up being given a function that takes a more specialized type, but invokes the function with a less specialized type. In practice, this sort of error is rare, and allowing this enables many common JavaScript patterns. A brief example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">enum</span> EventType { Mouse, Keyboard }
<span style="color:Blue;">interface</span> Event { timestamp: number; }
<span style="color:Blue;">interface</span> MouseEvent <span style="color:Blue;">extends</span> Event { x: number; y: number }
<span style="color:Blue;">interface</span> KeyEvent <span style="color:Blue;">extends</span> Event { keyCode: number }
<span style="color:Blue;">function</span> listenEvent(eventType: EventType, handler: (n: Event) =&gt; <span style="color:Blue;">void</span>) {
<span style="color:Green;">/* ... */</span>
}
<span style="color:Green;">// Unsound, but useful and common</span>
listenEvent(EventType.Mouse, (e: MouseEvent) =&gt; console.log(e.x + <span style="color:#A31515;">&#39;,&#39;</span> + e.y));
<span style="color:Green;">// Undesirable alternatives in presence of soundness</span>
listenEvent(EventType.Mouse, (e: Event) =&gt; console.log((&lt;MouseEvent&gt;e).x + <span style="color:#A31515;">&#39;,&#39;</span> + (&lt;MouseEvent&gt;e).y));
listenEvent(EventType.Mouse, &lt;(e: Event) =&gt; <span style="color:Blue;">void</span>&gt;((e: MouseEvent) =&gt; console.log(e.x + <span style="color:#A31515;">&#39;,&#39;</span> + e.y)));
<span style="color:Green;">// Still disallowed (clear error). Type safety enforced for wholly incompatible types</span>
listenEvent(EventType.Mouse, (e: number) =&gt; console.log(e));
</pre></div>
<h2>Optional Arguments and Rest Arguments</h2>
When comparing functions for compatibility, optional and required parameters are interchangeable. Extra optional parameters of the source type are not an error, and optional parameters of the target type without corresponding parameters in the target type are not an error.<br /><br />When a function has a rest parameter, it is treated as if it were an infinite series of optional parameters.<br /><br />This is unsound from a type system perspective, but from a runtime point of view the idea of an optional parameter is generally not well-enforced since passing ‘undefined’ in that position is equivalent for most functions.<br /><br />The motivating example is the common pattern of a function that takes a callback and invokes it with some predictable (to the programmer) but unknown (to the type system) number of arguments:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> invokeLater(args: any[], callback: (...args: any[]) =&gt; <span style="color:Blue;">void</span>) {
<span style="color:Green;">/* ... Invoke callback with &#39;args&#39; ... */</span>
}
<span style="color:Green;">// Unsound - invokeLater &quot;might&quot; provide any number of arguments</span>
invokeLater([1, 2], (x, y) =&gt; console.log(x + <span style="color:#A31515;">&#39;, &#39;</span> + y));
<span style="color:Green;">// Confusing (x and y are actually required) and undiscoverable</span>
invokeLater([1, 2], (x?, y?) =&gt; console.log(x + <span style="color:#A31515;">&#39;, &#39;</span> + y));
</pre></div>
<h2>Functions with overloads</h2>
When a function has overloads, each overload in the source type must be matched by a compatible signature on the target type. This ensures that the target function can be called in all the same situations as the source function. Functions with specialized overload signatures (those that use string literals in their overloads) do not use their specialized signatures when checking for compatibility.<br />
<h1>Enums</h1>
Enums are compatible with numbers, and numbers are compatible with enums. Enum values from different enum types are considered incompatible. For example,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">enum</span> Status { Ready, Waiting };
<span style="color:Blue;">enum</span> Color { Red, Blue, Green };
<span style="color:Blue;">var</span> status = Status.Ready;
status = Color.Green; <span style="color:Green;">//error</span>
</pre></div>
<h1>Classes</h1>
Classes work similarly to object literal types and interfaces with one exception: they have both a static and an instance type. When comparing two objects of a class type, only members of the instance are compared. Static members and constructors do not affect compatibility. <br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Animal {
feet: number;
constructor(name: string, numFeet: number) { }
}
<span style="color:Blue;">class</span> Size {
feet: number;
constructor(numFeet: number) { }
}
<span style="color:Blue;">var</span> a: Animal;
<span style="color:Blue;">var</span> s: Size;
a = s; <span style="color:Green;">//OK</span>
s = a; <span style="color:Green;">//OK</span>
</pre></div>
<h2>Private members in classes</h2>
Private members in a class affect their compatibility. When an instance of a class is checked for compatibility, if it contains a private member, the target type must also contain a private member that originated from the same class. This allows, for example, a class to be assignment compatible with its super class but not with classes from a different inheritance hierarchy which otherwise have the same shape.<br />
<h1>Generics</h1>
Because TypeScript is a structural type system, type parameters only affect the resulting type when consumed as part of the type of a member. For example,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Empty&lt;T&gt; {
}
<span style="color:Blue;">var</span> x: Empty&lt;number&gt;;
<span style="color:Blue;">var</span> y: Empty&lt;string&gt;;
x = y; <span style="color:Green;">// okay, y matches structure of x</span>
</pre></div><br />In the above, x and y are compatible because their structures do not use the type argument in a differentiating way. Changing this example by adding a member to Empty&lt;T&gt; shows how this works:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> NotEmpty&lt;T&gt; {
data: T;
}
<span style="color:Blue;">var</span> x: NotEmpty&lt;number&gt;;
<span style="color:Blue;">var</span> y: NotEmpty&lt;string&gt;;
x = y; <span style="color:Green;">// error, x and y are not compatible</span>
</pre></div><br />In this way, a generic type that has its type arguments specified acts just like a non-generic type.<br /><br />For generic types that do not have their type arguments specified, compatibility is checked by specifying &#39;any&#39; in place of all unspecified type arguments. The resulting types are then checked for compatibility, just as in the non-generic case.<br /><br />For example,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> identity = <span style="color:Blue;">function</span>&lt;T&gt;(x: T): T {
<span style="color:Green;">// ...</span>
}
<span style="color:Blue;">var</span> reverse = <span style="color:Blue;">function</span>&lt;U&gt;(y: U): U {
<span style="color:Green;">// ...</span>
}
identity = reverse; <span style="color:Green;">// Okay because (x: any)=&gt;any matches (y: any)=&gt;any</span>
</pre></div>
<h1>Advanced Topics</h1>
<h2>Subtype vs Assignment</h2>
So far, we&#39;ve used &#39;compatible&#39;, which is not a term defined in the language spec. In TypeScript, there are two kinds of compatibility: subtype and assignment. These differ only in that assignment extends subtype compatibility with rules to allow assignment to and from &#39;any&#39; and to and from enum with corresponding numeric values. <br /><br />Different places in the language use one of the two compatibility mechanisms, depending on the situation. For practical purposes, type compatibility is dictated by assignment compatibility even in the cases of the <span class="codeInline">implements</span> and <span class="codeInline">extends</span> clauses. For more information, see the <a href="http://go.microsoft.com/fwlink/?LinkId=267121">TypeScript spec</a>.<br /></div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:42:13 GMTUpdated Wiki: Type Compatibility in TypeScript 20141103044213PUpdated Wiki: Declaration Merginghttps://typescript.codeplex.com/wikipage?title=Declaration Merging&version=16<div class="wikidoc"><i><b>Please note:</b> This page is a work-in-progress. It may have errors and is subject to change.</i><br />
<h1>Introduction</h1>
Some of the unique concepts in TypeScript come from the need to describe what is happening to the shape of JavaScript objects at the type level. One example that is especially unique to TypeScript is the concept of &#39;declaration merging&#39;. Understanding this concept will give you an advantage when working with existing JavaScript in your TypeScript. It also opens the door to more advanced abstraction concepts.<br /><br />First, before we get into how declarations merge, let&#39;s first describe what we mean by &#39;declaration merging&#39;.<br /><br />For the purposes of this article, declaration merging specifically means that the compiler is doing the work of merging two separate declarations declared with the same name into a single definition. This merged definition has the features of both of the original declarations. Declaration merging is not limited to just two declarations, as any number of declarations can be merged. <br />
<h1>Basic Concepts</h1>
In TypeScript, a declaration exists in one of three groups: namespace/module, type, or value. Declarations that create a namespace/module are accessed using a dotted notation when writing a type. Declarations that create a type do just that, create a type that is visible with the declared shape and bound to the given name. Lastly, declarations create a value are those that are visible in the output JavaScript (eg, functions and variables).<br /><br /><table><tr><th> Declaration Type </th><th> Namespace </th><th> Type </th><th> Value </th></tr>
<tr><td> Module </td><td> X </td><td> </td><td> X </td></tr>
<tr><td> Class </td><td> </td><td> X </td><td> X </td></tr>
<tr><td> Interface </td><td> </td><td> X </td><td> </td></tr>
<tr><td> Function </td><td> </td><td> </td><td> X </td></tr>
<tr><td> Variable </td><td> </td><td> </td><td> X </td></tr></table><br /><br />Understanding what is created with each declaration will help you understand what is merged when you perform a declaration merge.<br />
<h1>Merging Interfaces</h1>
The simplest, and perhaps most common, type of declaration merging is interface merging. At the most basic level, the merge mechanically joins the members of both declarations into a single interface with the same name.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Box {
height: number;
width: number;
}
<span style="color:Blue;">interface</span> Box {
scale: number;
}
<span style="color:Blue;">var</span> box: Box = {height: 5, width: 6, scale: 10};
</pre></div><br />Non-function members of the interfaces must be unique. The compiler will issue an error if the interfaces both declare a non-function member of the same name.<br /><br />For function members, each function member of the same name is treated as describing an overload of the same function. Of note, too, is that in the case of interface A merging with later interface A (here called A&#39;), the overload set of A&#39; will have a higher precedence than that of interface A. <br /><br />That is, in the example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Document {
createElement(tagName: any): Element;
}
<span style="color:Blue;">interface</span> Document {
createElement(tagName: string): HTMLElement;
}
<span style="color:Blue;">interface</span> Document {
createElement(tagName: <span style="color:#A31515;">&quot;div&quot;</span>): HTMLDivElement;
createElement(tagName: <span style="color:#A31515;">&quot;span&quot;</span>): HTMLSpanElement;
createElement(tagName: <span style="color:#A31515;">&quot;canvas&quot;</span>): HTMLCanvasElement;
}
</pre></div><br />The two interfaces will merge to create a single declaration. Notice that the elements of each group maintains the same order, just the groups themselves are merged with later overload sets coming first:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Document {
createElement(tagName: <span style="color:#A31515;">&quot;div&quot;</span>): HTMLDivElement;
createElement(tagName: <span style="color:#A31515;">&quot;span&quot;</span>): HTMLSpanElement;
createElement(tagName: <span style="color:#A31515;">&quot;canvas&quot;</span>): HTMLCanvasElement;
createElement(tagName: string): HTMLElement;
createElement(tagName: any): Element;
}
</pre></div><br />
<h1>Merging Modules</h1>
Similarly to interfaces, modules of the same name will also merge their members. Since modules create both a namespace and a value, we need to understand how both merge.<br /><br />To merge the namespaces, type definitions from exported interfaces declared in each module are themselves merged, forming a single namespace with merged interface definitions inside.<br /><br />To merge the value, at each declaration site, if a module already exists with the given name, it is further extended by taking the existing module and adding the exported members of the second module to the first. <br /><br />The declaration merge of &#39;Animals&#39; in this example:<br /><div style="color:Black;background-color:White;"><pre>
module Animals {
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> Zebra { }
}
module Animals {
<span style="color:Blue;">export</span> <span style="color:Blue;">interface</span> Legged { numberOfLegs: number; }
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> Dog { }
}
</pre></div><br />is equivalent to:<br /><br /><div style="color:Black;background-color:White;"><pre>
module Animals {
<span style="color:Blue;">export</span> <span style="color:Blue;">interface</span> Legged { numberOfLegs: number; }
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> Zebra { }
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> Dog { }
}
</pre></div><br />This model of module merging is a helpful starting place, but to get a more complete picture we need to also understand what happens with non-exported members. Non-exported members are only visible in the original (un-merged) module. This means that after merging, merged members that came from other declarations can not see non-exported members.<br /><br />We can see this more clearly in this example:<br /><br /><div style="color:Black;background-color:White;"><pre>
module Animal {
<span style="color:Blue;">var</span> haveMuscles = <span style="color:Blue;">true</span>;
<span style="color:Blue;">export</span> <span style="color:Blue;">function</span> animalsHaveMuscles() {
<span style="color:Blue;">return</span> haveMuscles;
}
}
module Animal {
<span style="color:Blue;">export</span> <span style="color:Blue;">function</span> doAnimalsHaveMuscles() {
<span style="color:Blue;">return</span> haveMuscles; <span style="color:Green;">// &lt;-- error, haveMuscles is not visible here</span>
}
}
</pre></div><br />Because <span class="codeInline">haveMuscles</span> is not exported, only the <span class="codeInline">animalsHaveMuscles</span> function that shares the same un-merged module can see the symbol. The <span class="codeInline">doAnimalsHaveMuscles</span> function, even though it&#39;s part of the merged Animal module can not see this un-exported member.<br />
<h1>Merging Modules with Classes, Functions, and Enums</h1>
Modules are flexible enough to also merge with other types of declarations. To do so, the module declaration must follow the declaration it will merge with. The resulting declaration has properties of both declaration types. TypeScript uses this capability to model some of patterns in JavaScript as well as other programming languages.<br /><br />The first module merge we&#39;ll cover is merging a module with a class. This gives the user a way of describing inner classes.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Album {
label: Album.AlbumLabel;
}
module Album {
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> AlbumLabel { }
}
</pre></div><br />The visibility rules for merged members is the same as described in the &#39;Merging Modules&#39; section, so we must export the AlbumLabel class for the merged class to see it. The end result is a class managed inside of another class. You can also use modules to add more static members to an existing class.<br /><br />In addition to the pattern of inner classes, you may also be familiar with JavaScript practice of creating a function and then extending the function further by adding properties onto the function. TypeScript uses declaration merging to build up definitions like this in a type-safe way. <br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> buildLabel(name: string): string {
<span style="color:Blue;">return</span> buildLabel.prefix + name + buildLabel.suffix;
}
module buildLabel {
<span style="color:Blue;">export</span> <span style="color:Blue;">var</span> suffix = <span style="color:#A31515;">&quot;&quot;</span>;
<span style="color:Blue;">export</span> <span style="color:Blue;">var</span> prefix = <span style="color:#A31515;">&quot;Hello, &quot;</span>;
}
alert(buildLabel(<span style="color:#A31515;">&quot;Sam Smith&quot;</span>));
</pre></div><br />Similarly, modules can be used to extend enums with static members:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">enum</span> Color {
red = 1,
green = 2,
blue = 4
}
module Color {
<span style="color:Blue;">export</span> <span style="color:Blue;">function</span> mixColor(colorName: string) {
<span style="color:Blue;">if</span> (colorName == <span style="color:#A31515;">&quot;yellow&quot;</span>) {
<span style="color:Blue;">return</span> Color.red + Color.green;
}
<span style="color:Blue;">else</span> <span style="color:Blue;">if</span> (colorName == <span style="color:#A31515;">&quot;white&quot;</span>) {
<span style="color:Blue;">return</span> Color.red + Color.green + Color.blue;
}
<span style="color:Blue;">else</span> <span style="color:Blue;">if</span> (colorName == <span style="color:#A31515;">&quot;magenta&quot;</span>) {
<span style="color:Blue;">return</span> Color.red + Color.blue;
}
<span style="color:Blue;">else</span> <span style="color:Blue;">if</span> (colorName == <span style="color:#A31515;">&quot;cyan&quot;</span>) {
<span style="color:Blue;">return</span> Color.green + Color.blue;
}
}
}
</pre></div>
<h1>Disallowed Merges</h1>
Not all merges are allowed in TypeScript. Currently, classes can not merge with other classes, variables and classes can not merge, nor can interfaces and classes. For information on mimicking classes merging, see the <a href="https://typescript.codeplex.com/wikipage?title=Mixins%20in%20TypeScript&referringTitle=Declaration%20Merging">Mixins in TypeScript</a> section.</div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:40:26 GMTUpdated Wiki: Declaration Merging 20141103044026PUpdated Wiki: Generics in TypeScripthttps://typescript.codeplex.com/wikipage?title=Generics in TypeScript&version=7<div class="wikidoc"><i><b>Please note:</b> This page is a work-in-progress. It may have errors and is subject to change.</i><br />
<hr />
<h1>Introduction</h1>
A major part of software engineering is building components that not only have well-defined and consistent APIs, but are also reusable. Components that are capable of working on the data of today as well as the data of tomorrow will give you the most flexible capabilities for building up large software systems.<br /><br />In languages like C# and Java, one of the main tools in the toolbox for creating reusable components is &#39;generics&#39;, that is, being able to create a component that can work over a variety of types rather than a single one. This allows users to consume these components and use their own types.<br />
<h1>Hello World of Generics</h1>
To start off, let&#39;s do the &quot;hello world&quot; of generics: the identity function. The identity function is a function that will return back whatever is passed in. You can think of this in a similar way to the &#39;echo&#39; command. <br /><br />Without generics, we would either have to give the identity function a specific type:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity(arg: number): number {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />Or, we could describe the identity function using the &#39;any&#39; type:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity(arg: any): any {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />While using &#39;any&#39; is certainly generic in that will accept any and all types for the type of &#39;arg&#39;, we actually are losing the information about what that type was when the function returns. If we passed in a number, the only information we have is that any type could be returned. <br /><br />Instead, we need a way of capturing the type of the argument in such a way that we can also use it to denote what is being returned. Here, we will use a <i>type variable</i>, a special kind of variable that works on types rather than values. <br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />We&#39;ve now added a type variable &#39;T&#39; to the identity function. This &#39;T&#39; allows us to capture the type the user provides (eg, number), so that we can use that information later. Here, we use &#39;T&#39; again as the return type. On inspection, we can now see the same type is used for the argument and the return type. This allows us to traffic that type information in one side of the function and out the other.<br /><br />We say that this version of the &#39;identity&#39; function is generic, as it works over a range of types. Unlike using &#39;any&#39;, it&#39;s also just as precise (ie, it doesn&#39;t lose any information) as the first &#39;identity&#39; function that used numbers for the argument and return type.<br /><br />Once we&#39;ve written the generic identity function, we can call it in one of two ways. The first way is to pass all of the arguments, including the type argument, to the function:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> output = identity&lt;string&gt;(<span style="color:#A31515;">&quot;myString&quot;</span>); <span style="color:Green;">// type of output will be &#39;string&#39;</span>
</pre></div><br />Here we explicitly set &#39;T&#39; to be string as one of the arguments to the function call, denoted using the &lt;&gt; around the arguments rather than ().<br /><br />The second way is also perhaps the most common. Here we use /type argument inference/, that is, we want the compiler to set the value of T for us automatically based on the type of the argument we pass in:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> output = identity(<span style="color:#A31515;">&quot;myString&quot;</span>); <span style="color:Green;">// type of output will be &#39;string&#39;</span>
</pre></div><br />Notice that we didn&#39;t have explicitly pass the type in the angle brackets (&lt;&gt;), the compiler just looked at the value &quot;myString&quot;, and set T to its type. While type argument inference can be a helpful tool to keep code shorter and more readable, you may need to explicitly pass in the type arguments as we did in the previous example when the compiler fails to infer the type, as may happen in more complex examples.<br />
<h1>Working with Generic Type Variables</h1>
When you begin to use generics, you&#39;ll notice that when you create generic functions like &#39;identity&#39;, the compiler will enforce that you use any generically typed parameters in the body of the function correctly. That is, that you actually treat these parameters as if they could be any and all types.<br /><br />Let&#39;s take our &#39;identity&#39; function from earlier:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />What if want to also log the length of the argument &#39;arg&#39; to the console with each call. We might be tempted to write this:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: T): T {
console.log(arg.length); <span style="color:Green;">// Error: T doesn&#39;t have .length</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />When we do, the compiler will give us an error that we&#39;re using the &quot;.length&quot; member of &#39;arg&#39;, but nowhere have we said that &#39;arg&#39; has this member. Remember, we said earlier that these type variables stand in for any and all types, so someone using this function could have passed in a &#39;number&#39; instead, which does not have a &quot;.length&quot; member. <br /><br />Let&#39;s say that we&#39;ve actually intended this function to work on arrays of T rather that T directly. Since we&#39;re working with arrays, the .length member should be available. We can describe this just like we would create arrays of other types:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: T[]): T[] {
console.log(arg.length); <span style="color:Green;">// Array has a .length, so no more error</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />You can read the type of logging Identity as &quot;the generic function loggingIdentity, takes a type parameter T, and an argument &#39;arg&#39; which is an array of these T&#39;s, and returns an array of T&#39;s. If we passed in an array of numbers, we&#39;d get an array of numbers back out, as T would bind to number. This allows us to use our generic type variable &#39;T&#39; as part of the types we&#39;re working with, rather than the whole type, giving us greater flexibility. <br /><br />We can alternatively write the sample example this way:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: Array&lt;T&gt;): Array&lt;T&gt; {
console.log(arg.length); <span style="color:Green;">// Array has a .length, so no more error</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />You may already be familiar with this style of type from other languages. In the next section, we&#39;ll cover how you can create your own generic types like Array&lt;T&gt;.<br />
<h1>Generic Types</h1>
In previous sections, we created generic identity functions that worked over a range of types. In this section, we&#39;ll explore the type of the functions themselves and how to create generic interfaces.<br /><br />The type of generic functions is just like those of non-generic functions, with the type parameters listed first, similarly to function declarations:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: &lt;T&gt;(arg: T)=&gt;T = identity;
</pre></div><br />We could also have used a different name for the generic type parameter in the type, so long as the number of type variables and how the type variables are used line up.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: &lt;U&gt;(arg: U)=&gt;U = identity;
</pre></div><br />We can also write the generic type as a call signature of an object literal type:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: {&lt;T&gt;(arg: T): T} = identity;
</pre></div><br />Which leads us to writing our first generic interface. Let&#39;s take the object literal from the previous example and move it to an interface:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> GenericIdentityFn {
&lt;T&gt;(arg: T): T;
}
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: GenericIdentityFn = identity;
</pre></div><br />In a similar example, we may want to move the generic parameter to be a parameter of the whole interface. This lets us see what type(s) we&#39;re generic over (eg Dictionary&lt;string&gt; rather than just Dictionary). This makes the type parameter visible to all the other members of the interface. <br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> GenericIdentityFn&lt;T&gt; {
(arg: T): T;
}
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: GenericIdentityFn&lt;number&gt; = identity;
</pre></div><br />Notice that our example has changed to be something slightly different. Instead of describing a generic function, we now have a non-generic function signature that is a part of a generic type. When we use GenericIdentityFn, we now will also need to specify the corresponding type argument (here: number), effectively locking in what the underlying call signature will use. Understanding when to put the type parameter directly on the call signature and when to put it on the interface itself will be helpful in describing what aspects of a type are generic.<br /><br />In addition to generic interfaces, we can also create generic classes. Note that it is not possible to create generic enums and modules.<br />
<h1>Generic Classes</h1>
A generic class has a similar shape to a generic interface. Generic classes have a generic type parameter list in angle brackets (&lt;&gt;) following the name of the class.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> GenericNumber&lt;T&gt; {
zeroValue: T;
add: (x: T, y: T) =&gt; T;
}
<span style="color:Blue;">var</span> myGenericNumber = <span style="color:Blue;">new</span> GenericNumber&lt;number&gt;();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = <span style="color:Blue;">function</span>(x, y) { <span style="color:Blue;">return</span> x + y; };
</pre></div><br />This is a pretty literal use of the &#39;GenericNumber&#39; class, but you may have noticed that nothing is restricting is to only use the &#39;number&#39; type. We could have instead used &#39;string&#39; or even more complex objects.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> stringNumeric = <span style="color:Blue;">new</span> GenericNumber&lt;string&gt;();
stringNumeric.zeroValue = <span style="color:#A31515;">&quot;&quot;</span>;
stringNumeric.add = <span style="color:Blue;">function</span>(x, y) { <span style="color:Blue;">return</span> x + y; };
alert(stringNumeric.add(stringNumeric.zeroValue, <span style="color:#A31515;">&quot;test&quot;</span>));
</pre></div><br />Just as with interface, putting the type parameter on the class itself lets us make sure all of the properties of the class are working with the same type.<br /><br />As we covered in <a href="https://typescript.codeplex.com/wikipage?title=Classes%20in%20TypeScript&referringTitle=Generics%20in%20TypeScript">Classes</a>, a class has two side to its type: the static side and the instance side. Generic classes are only generic over their instance side rather than their static side, so when working with classes, static members can not use the class&#39;s type parameter.<br />
<h1>Generic Constraints</h1>
If you remember from an earlier example, you may sometimes want to write a generic function that works on a set of types where you have some knowledge about what capabilities that set of types will have. In our &#39;loggingIdentity&#39; example, we wanted to be able access the &quot;.length&quot; property of &#39;arg&#39;, but the compiler could not prove that every type had a &quot;.length&quot; property, so it warns us that we can&#39;t make this assumption.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: T): T {
console.log(arg.length); <span style="color:Green;">// Error: T doesn&#39;t have .length</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />Instead of working with any and all types, we&#39;d like to constrain this function to work with any and all types that also have the &quot;.length&quot; property. As long as the type has this member, we&#39;ll allow it, but it&#39;s required to have at least this member. To do so, we must list our requirement as a constraint on what T can be.<br /><br />To do so, we&#39;ll create an interface that describes our constraint. Here, we&#39;ll create an interface that has a single &quot;.length&quot; property and then we&#39;ll use this interface and the <span class="codeInline">extends</span> keyword to denote our constraint:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Lengthwise {
length: number;
}
<span style="color:Blue;">function</span> loggingIdentity&lt;T <span style="color:Blue;">extends</span> Lengthwise&gt;(arg: T): T {
console.log(arg.length); <span style="color:Green;">// Now we know it has a .length property, so no more error</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />Because the generic function is now constrained, it will no longer work over any and all types:<br /><br /><div style="color:Black;background-color:White;"><pre>
loggingIdentity(3); <span style="color:Green;">// Error, number doesn&#39;t have a .length property</span>
</pre></div><br />Instead, we need to pass in values whose type has all the required properties:<br /><br /><div style="color:Black;background-color:White;"><pre>
loggingIdentity({length: 10, value: 3});
</pre></div>
<h2>Using Type Parameters in Generic Constraints</h2>
In some cases, it may be useful to declare a type parameter that is constrained by another type parameter. For example,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> find&lt;T, U <span style="color:Blue;">extends</span> Findable&lt;T&gt;&gt;(n: T, s: U) { <span style="color:Green;">// errors because type parameter used in constraint</span>
<span style="color:Green;">// ...</span>
}
find (giraffe, myAnimals);
</pre></div><br />You can achieve the pattern above by replacing the type parameter with its constraint. Rewriting the example above,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> find&lt;T&gt;(n: T, s: Findable&lt;T&gt;) {
<span style="color:Green;">// ...</span>
}
find(giraffe, myAnimals);
</pre></div><br /><i>Note:</i> The above is not strictly identical, as the return type of the first function could have returned &#39;U&#39;, which the second function pattern does not provide a means to do.<br />
<h2>Using Class Types in Generics</h2>
When creating factories in TypeScript using generics, it is necessary to refer to class types by their constructor functions. For example,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> create&lt;T&gt;(c: {<span style="color:Blue;">new</span>(): T; }): T {
<span style="color:Blue;">return</span> <span style="color:Blue;">new</span> c();
}
</pre></div><br />A more advanced example uses the prototype property to infer and constrain relationships between the constructor function and the instance side of class types.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> BeeKeeper {
hasMask: <span style="color:Blue;">boolean</span>;
}
<span style="color:Blue;">class</span> ZooKeeper {
nametag: string;
}
<span style="color:Blue;">class</span> Animal {
numLegs: number;
}
<span style="color:Blue;">class</span> Bee <span style="color:Blue;">extends</span> Animal {
keeper: BeeKeeper;
}
<span style="color:Blue;">class</span> Lion <span style="color:Blue;">extends</span> Animal {
keeper: ZooKeeper;
}
<span style="color:Blue;">function</span> findKeeper&lt;A <span style="color:Blue;">extends</span> Animal, K&gt; (a: {<span style="color:Blue;">new</span>(): A;
prototype: {keeper: K}}): K {
<span style="color:Blue;">return</span> <span style="color:Blue;">null</span>;
}
findKeeper(Lion).nametag; <span style="color:Green;">// works!</span>
</pre></div></div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:39:25 GMTUpdated Wiki: Generics in TypeScript 20141103043925PUpdated Wiki: Generics in TypeScripthttps://typescript.codeplex.com/wikipage?title=Generics in TypeScript&version=6<div class="wikidoc"><i><b>Please note:</b> This page is a work-in-progress. It may have errors and is subject to change.</i><br />
<hr />
<h1>Introduction</h1>
A major part of software engineering is building components that not only have well-defined and consistent APIs, but are also reusable. Components that are capable of working on the data of today as well as the data of tomorrow will give you the most flexible capabilities for building up large software systems.<br /><br />In languages like C# and Java, one of the main tools in the toolbox for creating reusable components is &#39;generics&#39;, that is, being able to create a component that can work over a variety of types rather than a single one. This allows users to consume these components and use their own types.<br />
<h1>Hello World of Generics</h1>
To start off, let&#39;s do the &quot;hello world&quot; of generics: the identity function. The identity function is a function that will return back whatever is passed in. You can think of this in a similar way to the &#39;echo&#39; command. <br /><br />Without generics, we would either have to give the identity function a specific type:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity(arg: number): number {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />Or, we could describe the identity function using the &#39;any&#39; type:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity(arg: any): any {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />While using &#39;any&#39; is certainly generic in that will accept any and all types for the type of &#39;arg&#39;, we actually are losing the information about what that type was when the function returns. If we passed in a number, the only information we have is that any type could be returned. <br /><br />Instead, we need a way of capturing the type of the argument in such a way that we can also use it to denote what is being returned. Here, we will use a <i>type variable</i>, a special kind of variable that works on types rather than values. <br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />We&#39;ve now added a type variable &#39;T&#39; to the identity function. This &#39;T&#39; allows us to capture the type the user provides (eg, number), so that we can use that information later. Here, we use &#39;T&#39; again as the return type. On inspection, we can now see the same type is used for the argument and the return type. This allows us to traffic that type information in one side of the function and out the other.<br /><br />We say that this version of the &#39;identity&#39; function is generic, as it works over a range of types. Unlike using &#39;any&#39;, it&#39;s also just as precise (ie, it doesn&#39;t lose any information) as the first &#39;identity&#39; function that used numbers for the argument and return type.<br /><br />Once we&#39;ve written the generic identity function, we can call it in one of two ways. The first way is to pass all of the arguments, including the type argument, to the function:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> output = identity&lt;string&gt;(<span style="color:#A31515;">&quot;myString&quot;</span>); <span style="color:Green;">// type of output will be &#39;string&#39;</span>
</pre></div><br />Here we explicitly set &#39;T&#39; to be string as one of the arguments to the function call, denoted using the &lt;&gt; around the arguments rather than ().<br /><br />The second way is also perhaps the most common. Here we use /type argument inference/, that is, we want the compiler to set the value of T for us automatically based on the type of the argument we pass in:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> output = identity(<span style="color:#A31515;">&quot;myString&quot;</span>); <span style="color:Green;">// type of output will be &#39;string&#39;</span>
</pre></div><br />Notice that we didn&#39;t have explicitly pass the type in the angle brackets (&lt;&gt;), the compiler just looked at the value &quot;myString&quot;, and set T to its type. While type argument inference can be a helpful tool to keep code shorter and more readable, you may need to explicitly pass in the type arguments as we did in the previous example when the compiler fails to infer the type, as may happen in more complex examples.<br />
<h1>Working with Generic Type Variables</h1>
When you begin to use generics, you&#39;ll notice that when you create generic functions like &#39;identity&#39;, the compiler will enforce that you use any generically typed parameters in the body of the function correctly. That is, that you actually treat these parameters as if they could be any and all types.<br /><br />Let&#39;s take our &#39;identity&#39; function from earlier:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />What if want to also log the length of the argument &#39;arg&#39; to the console with each call. We might be tempted to write this:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: T): T {
console.log(arg.length); <span style="color:Green;">// Error: T doesn&#39;t have .length</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />When we do, the compiler will give us an error that we&#39;re using the &quot;.length&quot; member of &#39;arg&#39;, but nowhere have we said that &#39;arg&#39; has this member. Remember, we said earlier that these type variables stand in for any and all types, so someone using this function could have passed in a &#39;number&#39; instead, which does not have a &quot;.length&quot; member. <br /><br />Let&#39;s say that we&#39;ve actually intended this function to work on arrays of T rather that T directly. Since we&#39;re working with arrays, the .length member should be available. We can describe this just like we would create arrays of other types:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: T[]): T[] {
console.log(arg.length); <span style="color:Green;">// Array has a .length, so no more error</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />You can read the type of logging Identity as &quot;the generic function loggingIdentity, takes a type parameter T, and an argument &#39;arg&#39; which is an array of these T&#39;s, and returns an array of T&#39;s. If we passed in an array of numbers, we&#39;d get an array of numbers back out, as T would bind to number. This allows us to use our generic type variable &#39;T&#39; as part of the types we&#39;re working with, rather than the whole type, giving us greater flexibility. <br /><br />We can alternatively write the sample example this way:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: Array&lt;T&gt;): Array&lt;T&gt; {
console.log(arg.length); <span style="color:Green;">// Array has a .length, so no more error</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />You may already be familiar with this style of type from other languages. In the next section, we&#39;ll cover how you can create your own generic types like Array&lt;T&gt;.<br />
<h1>Generic Types</h1>
In previous sections, we created generic identity functions that worked over a range of types. In this section, we&#39;ll explore the type of the functions themselves and how to create generic interfaces.<br /><br />The type of generic functions is just like those of non-generic functions, with the type parameters listed first, similarly to function declarations:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: &lt;T&gt;(arg: T)=&gt;T = identity;
</pre></div><br />We could also have used a different name for the generic type parameter in the type, so long as the number of type variables and how the type variables are used line up.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: &lt;U&gt;(arg: U)=&gt;U = identity;
</pre></div><br />We can also write the generic type as a call signature of an object literal type:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: {&lt;T&gt;(arg: T): T} = identity;
</pre></div><br />Which leads us to writing our first generic interface. Let&#39;s take the object literal from the previous example and move it to an interface:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> GenericIdentityFn {
&lt;T&gt;(arg: T): T;
}
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: GenericIdentityFn = identity;
</pre></div><br />In a similar example, we may want to move the generic parameter to be a parameter of the whole interface. This lets us see what type(s) we&#39;re generic over (eg Dictionary&lt;string&gt; rather than just Dictionary). This makes the type parameter visible to all the other members of the interface. <br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> GenericIdentityFn&lt;T&gt; {
(arg: T): T;
}
<span style="color:Blue;">function</span> identity&lt;T&gt;(arg: T): T {
<span style="color:Blue;">return</span> arg;
}
<span style="color:Blue;">var</span> myIdentity: GenericIdentityFn&lt;number&gt; = identity;
</pre></div><br />Notice that our example has changed to be something slightly different. Instead of describing a generic function, we now have a non-generic function signature that is a part of a generic type. When we use GenericIdentityFn, we now will also need to specify the corresponding type argument (here: number), effectively locking in what the underlying call signature will use. Understanding when to put the type parameter directly on the call signature and when to put it on the interface itself will be helpful in describing what aspects of a type are generic.<br /><br />In addition to generic interfaces, we can also create generic classes. Note that it is not possible to create generic enums and modules.<br />
<h1>Generic Classes</h1>
A generic class has a similar shape to a generic interface. Generic classes have a generic type parameter list in angle brackets (&lt;&gt;) following the name of the class.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> GenericNumber&lt;T&gt; {
zeroValue: T;
add: (x: T, y: T) =&gt; T;
}
<span style="color:Blue;">var</span> myGenericNumber = <span style="color:Blue;">new</span> GenericNumber&lt;number&gt;();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = <span style="color:Blue;">function</span>(x, y) { <span style="color:Blue;">return</span> x + y; };
</pre></div><br />This is a pretty literal use of the &#39;GenericNumber&#39; class, but you may have noticed that nothing is restricting is to only use the &#39;number&#39; type. We could have instead used &#39;string&#39; or even more complex objects.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> stringNumeric = <span style="color:Blue;">new</span> GenericNumber&lt;string&gt;();
stringNumeric.zeroValue = <span style="color:#A31515;">&quot;&quot;</span>;
stringNumeric.add = <span style="color:Blue;">function</span>(x, y) { <span style="color:Blue;">return</span> x + y; };
alert(stringNumeric.add(stringNumeric.zeroValue, <span style="color:#A31515;">&quot;test&quot;</span>));
</pre></div><br />Just as with interface, putting the type parameter on the class itself lets us make sure all of the properties of the class are working with the same type.<br /><br />As we covered in <a href="https://typescript.codeplex.com/wikipage?title=Classes%20in%20TypeScript&referringTitle=Generics%20in%20TypeScript">Classes</a>, a class has two side to its type: the static side and the instance side. Generic classes are only generic over their instance side rather than their static side, so when working with classes, static members can not use the class&#39;s type parameter.<br />
<h1>Generic Constraints</h1>
If you remember from an earlier example, you may sometimes want to write a generic function that works on a set of types where you have some knowledge about what capabilities that set of types will have. In our &#39;loggingIdentity&#39; example, we wanted to be able access the &quot;.length&quot; property of &#39;arg&#39;, but the compiler could not prove that every type had a &quot;.length&quot; property, so it warns us that we can&#39;t make this assumption.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> loggingIdentity&lt;T&gt;(arg: T): T {
console.log(arg.length); <span style="color:Green;">// Error: T doesn&#39;t have .length</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />Instead of working with any and all types, we&#39;d like to constrain this function to work with any and all types that also have the &quot;.length&quot; property. As long as the type has this member, we&#39;ll allow it, but it&#39;s required to have at least this member. To do so, we must list our requirement as a constraint on what T can be.<br /><br />To do so, we&#39;ll create an interface that describes our constraint. Here, we&#39;ll create an interface that has a single &quot;.length&quot; property and then we&#39;ll use this interface and the <span class="codeInline">extends</span> keyword to denote our constraint:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Lengthwise {
length: number;
}
<span style="color:Blue;">function</span> loggingIdentity&lt;T <span style="color:Blue;">extends</span> Lengthwise&gt;(arg: T): T {
console.log(arg.length); <span style="color:Green;">// Now we know it has a .length property, so no more error</span>
<span style="color:Blue;">return</span> arg;
}
</pre></div><br />Because the generic function is now constrained, it will no longer work over any and all types:<br /><br /><div style="color:Black;background-color:White;"><pre>
loggingIdentity(3); <span style="color:Green;">// Error, number doesn&#39;t have a .length property</span>
</pre></div><br />Instead, we need to pass in values whose type has all the required properties:<br /><br /><div style="color:Black;background-color:White;"><pre>
loggingIdentity({length: 10, value: 3});
</pre></div>
<h2>Using Type Parameters in Generic Constraints</h2>
In some cases, it may be useful to declare a type parameter that is constrained by another type parameter. For example,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> find&lt;T, U <span style="color:Blue;">extends</span> Findable&lt;T&gt;&gt;(n: T, s: U) { <span style="color:Green;">// errors because type parameter used in constraint</span>
<span style="color:Green;">// ...</span>
}
find (giraffe, myAnimals);
</pre></div><br />You can achieve the pattern above by replacing the type parameter with its constraint. Rewriting the example above,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> find&lt;T&gt;(n: T, s: Findable&lt;T&gt;) { <span style="color:Green;">// errors because type parameter used in constraint</span>
<span style="color:Green;">// ...</span>
}
find(giraffe, myAnimals);
</pre></div><br /><i>Note:</i> The above is not strictly identical, as the return type of the first function could have returned &#39;U&#39;, which the second function pattern does not provide a means to do.<br />
<h2>Using Class Types in Generics</h2>
When creating factories in TypeScript using generics, it is necessary to refer to class types by their constructor functions. For example,<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> create&lt;T&gt;(c: {<span style="color:Blue;">new</span>(): T; }): T {
<span style="color:Blue;">return</span> <span style="color:Blue;">new</span> c();
}
</pre></div><br />A more advanced example uses the prototype property to infer and constrain relationships between the constructor function and the instance side of class types.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> BeeKeeper {
hasMask: <span style="color:Blue;">boolean</span>;
}
<span style="color:Blue;">class</span> ZooKeeper {
nametag: string;
}
<span style="color:Blue;">class</span> Animal {
numLegs: number;
}
<span style="color:Blue;">class</span> Bee <span style="color:Blue;">extends</span> Animal {
keeper: BeeKeeper;
}
<span style="color:Blue;">class</span> Lion <span style="color:Blue;">extends</span> Animal {
keeper: ZooKeeper;
}
<span style="color:Blue;">function</span> findKeeper&lt;A <span style="color:Blue;">extends</span> Animal, K&gt; (a: {<span style="color:Blue;">new</span>(): A;
prototype: {keeper: K}}): K {
<span style="color:Blue;">return</span> <span style="color:Blue;">null</span>;
}
findKeeper(Lion).nametag; <span style="color:Green;">// works!</span>
</pre></div></div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:38:25 GMTUpdated Wiki: Generics in TypeScript 20141103043825PUpdated Wiki: Modules in TypeScripthttps://typescript.codeplex.com/wikipage?title=Modules in TypeScript&version=17<div class="wikidoc"><i><b>Please note:</b> This page is a work-in-progress. It may have errors and is subject to change.</i><br />
<hr />
<h1>Introduction</h1>
This post outlines the various ways to organize your code using modules in TypeScript. We&#39;ll be covering internal and external modules and we&#39;ll discuss when each is appropriate and how to use them. We&#39;ll also go over some advanced topics of how to use external modules, and address some common pitfalls when using modules in TypeScript.<br />
<h3>First steps</h3>
Let&#39;s start with the program we&#39;ll be using as our example throughout this page. We&#39;ve written a small set of simplistic string validators, like you might use when checking a user&#39;s input on a form in a webpage or checking the format of an externally-provided data file.<br />
<h5>Validators in a single file</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> StringValidator {
isAcceptable(s: string): <span style="color:Blue;">boolean</span>;
}
<span style="color:Blue;">var</span> lettersRegexp = /^[A-Za-z]+$/;
<span style="color:Blue;">var</span> numberRegexp = /^[0-9]+$/;
<span style="color:Blue;">class</span> LettersOnlyValidator <span style="color:Blue;">implements</span> StringValidator {
isAcceptable(s: string) {
<span style="color:Blue;">return</span> lettersRegexp.test(s);
}
}
<span style="color:Blue;">class</span> ZipCodeValidator <span style="color:Blue;">implements</span> StringValidator {
isAcceptable(s: string) {
<span style="color:Blue;">return</span> s.length === 5 &amp;&amp; numberRegexp.test(s);
}
}
<span style="color:Green;">// Some samples to try</span>
<span style="color:Blue;">var</span> strings = [<span style="color:#A31515;">&#39;Hello&#39;</span>, <span style="color:#A31515;">&#39;98052&#39;</span>, <span style="color:#A31515;">&#39;101&#39;</span>];
<span style="color:Green;">// Validators to use</span>
<span style="color:Blue;">var</span> validators: { [s: string]: StringValidator; } = {};
validators[<span style="color:#A31515;">&#39;ZIP code&#39;</span>] = <span style="color:Blue;">new</span> ZipCodeValidator();
validators[<span style="color:#A31515;">&#39;Letters only&#39;</span>] = <span style="color:Blue;">new</span> LettersOnlyValidator();
<span style="color:Green;">// Show whether each string passed each validator</span>
strings.forEach(s =&gt; {
<span style="color:Blue;">for</span> (<span style="color:Blue;">var</span> name <span style="color:Blue;">in</span> validators) {
console.log(<span style="color:#A31515;">&#39;&quot;&#39;</span> + s + <span style="color:#A31515;">&#39;&quot; &#39;</span> + (validators[name].isAcceptable(s) ? <span style="color:#A31515;">&#39; matches &#39;</span> : <span style="color:#A31515;">&#39; does not match &#39;</span>) + name);
}
});
</pre></div>
<h3>Adding Modularity</h3>
As we add more validators, we&#39;re going to want to have some kind of organization scheme so that we can keep track of our types and not worry about name collisions with other objects. Instead of putting lots of different names into the global namespace, let&#39;s wrap up our objects into a module.<br /><br />In this example, we&#39;ve moved all the Validator-related types into a module called <i>Validation</i>. Because we want the interfaces and classes here to be visible outside the module, we preface them with <i>export</i>. Conversely, the variables <i>lettersRegexp</i> and <i>numberRegexp</i> are implementation details, so they are left unexported and will not be visible to code outside the module. In the test code at the bottom of the file, we now need to qualify the names of the types when used outside the module, e.g. <i>Validation.LettersOnlyValidator</i>.<br />
<h5>Modularized Validators</h5>
<div style="color:Black;background-color:White;"><pre>
module Validation {
<span style="color:Blue;">export</span> <span style="color:Blue;">interface</span> StringValidator {
isAcceptable(s: string): <span style="color:Blue;">boolean</span>;
}
<span style="color:Blue;">var</span> lettersRegexp = /^[A-Za-z]+$/;
<span style="color:Blue;">var</span> numberRegexp = /^[0-9]+$/;
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> LettersOnlyValidator <span style="color:Blue;">implements</span> StringValidator {
isAcceptable(s: string) {
<span style="color:Blue;">return</span> lettersRegexp.test(s);
}
}
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> ZipCodeValidator <span style="color:Blue;">implements</span> StringValidator {
isAcceptable(s: string) {
<span style="color:Blue;">return</span> s.length === 5 &amp;&amp; numberRegexp.test(s);
}
}
}
<span style="color:Green;">// Some samples to try</span>
<span style="color:Blue;">var</span> strings = [<span style="color:#A31515;">&#39;Hello&#39;</span>, <span style="color:#A31515;">&#39;98052&#39;</span>, <span style="color:#A31515;">&#39;101&#39;</span>];
<span style="color:Green;">// Validators to use</span>
<span style="color:Blue;">var</span> validators: { [s: string]: Validation.StringValidator; } = {};
validators[<span style="color:#A31515;">&#39;ZIP code&#39;</span>] = <span style="color:Blue;">new</span> Validation.ZipCodeValidator();
validators[<span style="color:#A31515;">&#39;Letters only&#39;</span>] = <span style="color:Blue;">new</span> Validation.LettersOnlyValidator();
<span style="color:Green;">// Show whether each string passed each validator</span>
strings.forEach(s =&gt; {
<span style="color:Blue;">for</span> (<span style="color:Blue;">var</span> name <span style="color:Blue;">in</span> validators) {
console.log(<span style="color:#A31515;">&#39;&quot;&#39;</span> + s + <span style="color:#A31515;">&#39;&quot; &#39;</span> + (validators[name].isAcceptable(s) ? <span style="color:#A31515;">&#39; matches &#39;</span> : <span style="color:#A31515;">&#39; does not match &#39;</span>) + name);
}
});
</pre></div>
<h1>Splitting Across Files</h1>
As our application grows, we&#39;ll want to split the code across multiple files to make it easier to maintain.<br /><br />Here, we&#39;ve split our Validation module across many files. Even though the files are separate, they can each contribute to the same module and can be consumed as if they were all defined in one place. Because there are dependencies between files, we&#39;ve added reference tags to tell the compiler about the relationships between the files. Our test code is otherwise unchanged.<br />
<h3>Multi-file internal modules</h3>
<h5>Validation.ts</h5>
<div style="color:Black;background-color:White;"><pre>
module Validation {
<span style="color:Blue;">export</span> <span style="color:Blue;">interface</span> StringValidator {
isAcceptable(s: string): <span style="color:Blue;">boolean</span>;
}
}
</pre></div><h5>LettersOnlyValidator.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">/// &lt;reference path=&quot;Validation.ts&quot; /&gt;</span>
module Validation {
<span style="color:Blue;">var</span> lettersRegexp = /^[A-Za-z]+$/;
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> LettersOnlyValidator <span style="color:Blue;">implements</span> StringValidator {
isAcceptable(s: string) {
<span style="color:Blue;">return</span> lettersRegexp.test(s);
}
}
}
</pre></div>
<h5>ZipCodeValidator.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">/// &lt;reference path=&quot;Validation.ts&quot; /&gt;</span>
module Validation {
<span style="color:Blue;">var</span> numberRegexp = /^[0-9]+$/;
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> ZipCodeValidator <span style="color:Blue;">implements</span> StringValidator {
isAcceptable(s: string) {
<span style="color:Blue;">return</span> s.length === 5 &amp;&amp; numberRegexp.test(s);
}
}
}
</pre></div>
<h5>Test.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">/// &lt;reference path=&quot;Validation.ts&quot; /&gt;</span>
<span style="color:Green;">/// &lt;reference path=&quot;LettersOnlyValidator.ts&quot; /&gt;</span>
<span style="color:Green;">/// &lt;reference path=&quot;ZipCodeValidator.ts&quot; /&gt;</span>
<span style="color:Green;">// Some samples to try</span>
<span style="color:Blue;">var</span> strings = [<span style="color:#A31515;">&#39;Hello&#39;</span>, <span style="color:#A31515;">&#39;98052&#39;</span>, <span style="color:#A31515;">&#39;101&#39;</span>];
<span style="color:Green;">// Validators to use</span>
<span style="color:Blue;">var</span> validators: { [s: string]: Validation.StringValidator; } = {};
validators[<span style="color:#A31515;">&#39;ZIP code&#39;</span>] = <span style="color:Blue;">new</span> Validation.ZipCodeValidator();
validators[<span style="color:#A31515;">&#39;Letters only&#39;</span>] = <span style="color:Blue;">new</span> Validation.LettersOnlyValidator();
<span style="color:Green;">// Show whether each string passed each validator</span>
strings.forEach(s =&gt; {
<span style="color:Blue;">for</span> (<span style="color:Blue;">var</span> name <span style="color:Blue;">in</span> validators) {
console.log(<span style="color:#A31515;">&#39;&quot;&#39;</span> + s + <span style="color:#A31515;">&#39;&quot; &#39;</span> + (validators[name].isAcceptable(s) ? <span style="color:#A31515;">&#39; matches &#39;</span> : <span style="color:#A31515;">&#39; does not match &#39;</span>) + name);
}
});
</pre></div><br />Once there are multiple files involved, we&#39;ll need to make sure all of the compiled code gets loaded. There are two ways of doing this.<br /><br />First, we can use concatenated output using the <i>--out</i> flag to compile all of the input files into a single JavaScript output file:<br /><pre>
tsc --out sample.js Test.ts
</pre><br />The compiler will automatically order the output file based on the reference tags present in the files. You can also specify each file individually:<br /><pre>
tsc --out sample.js Validation.ts LettersOnlyValidator.ts ZipCodeValidator.ts Test.ts
</pre><br /><br />Alternatively, we can use per-file compilation (the default) to emit one JavaScript file for each input file. If multiple JS files get produced, we&#39;ll need to use <i>&lt;script&gt;</i> tags on our webpage to load each emitted file in the appropriate order, for example:<br />
<h5>MyTestPage.html (excerpt)</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">&lt;</span><span style="color:#A31515;">script</span> <span style="color:Red;">src</span><span style="color:Blue;">=</span><span style="color:Blue;">&quot;Validation.js&quot;</span> <span style="color:Red;">type</span><span style="color:Blue;">=</span><span style="color:Blue;">&quot;text/javascript&quot;</span> <span style="color:Blue;">/&gt;</span>
<span style="color:Blue;">&lt;</span><span style="color:#A31515;">script</span> <span style="color:Red;">src</span><span style="color:Blue;">=</span><span style="color:Blue;">&quot;LettersOnlyValidator.js&quot;</span> <span style="color:Red;">type</span><span style="color:Blue;">=</span><span style="color:Blue;">&quot;text/javascript&quot;</span> <span style="color:Blue;">/&gt;</span>
<span style="color:Blue;">&lt;</span><span style="color:#A31515;">script</span> <span style="color:Red;">src</span><span style="color:Blue;">=</span><span style="color:Blue;">&quot;ZipCodeValidator.js&quot;</span> <span style="color:Red;">type</span><span style="color:Blue;">=</span><span style="color:Blue;">&quot;text/javascript&quot;</span> <span style="color:Blue;">/&gt;</span>
<span style="color:Blue;">&lt;</span><span style="color:#A31515;">script</span> <span style="color:Red;">src</span><span style="color:Blue;">=</span><span style="color:Blue;">&quot;Test.js&quot;</span> <span style="color:Red;">type</span><span style="color:Blue;">=</span><span style="color:Blue;">&quot;text/javascript&quot;</span> <span style="color:Blue;">/&gt;</span>
</pre></div>
<h1>Going External</h1>
TypeScript also has the concept of an external module. External modules are used in two cases: node.js and require.js. Applications not using node.js or require.js do not need to use external modules and can best be organized using the internal module concept outlined above.<br /><br />In external modules, relationships between files are specified in terms of imports and exports at the file level. In TypeScript, any file containing a top-level <i>import</i> or <i>export</i> is considered an external module.<br /><br />Below, we have converted the previous example to use external modules. Notice that we no longer use the module keyword – the files themselves constitute a module and are identified by their filenames.<br /><br />The reference tags have been replaced with <i>import</i> statements that specify the dependencies between modules. The <i>import</i> statement has two parts: the name that the module will be known by in this file, and the require keyword that specifies the path to the required module:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">import</span> someMod = require(<span style="color:#A31515;">&#39;someModule&#39;</span>);
</pre></div><br />We specify which objects are visible outside the module by using the <i>export</i> keyword on a top-level declaration, similarly to how <i>export</i> defined the public surface area of an internal module.<br /><br />To compile, we must specify a module target on the command line. For node.js, use <i>--target commonjs</i>; for require.js, use <i>--target amd</i>. For example:<br /><pre>
tsc --module commonjs Test.ts
</pre><br />When compiled, each external module will become a separate .js file. Similar to reference tags, the compiler will follow <i>import</i> statements to compile dependent files.<br />
<h5>Validation.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">export</span> <span style="color:Blue;">interface</span> StringValidator {
isAcceptable(s: string): <span style="color:Blue;">boolean</span>;
}
</pre></div>
<h5>LettersOnlyValidator.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">import</span> validation = require(<span style="color:#A31515;">&#39;./Validation&#39;</span>);
<span style="color:Blue;">var</span> lettersRegexp = /^[A-Za-z]+$/;
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> LettersOnlyValidator <span style="color:Blue;">implements</span> validation.StringValidator {
isAcceptable(s: string) {
<span style="color:Blue;">return</span> lettersRegexp.test(s);
}
}
</pre></div>
<h5>ZipCodeValidator.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">import</span> validation = require(<span style="color:#A31515;">&#39;./Validation&#39;</span>);
<span style="color:Blue;">var</span> numberRegexp = /^[0-9]+$/;
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> ZipCodeValidator <span style="color:Blue;">implements</span> validation.StringValidator {
isAcceptable(s: string) {
<span style="color:Blue;">return</span> s.length === 5 &amp;&amp; numberRegexp.test(s);
}
}
</pre></div>
<h5>Test.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">import</span> validation = require(<span style="color:#A31515;">&#39;./Validation&#39;</span>);
<span style="color:Blue;">import</span> zip = require(<span style="color:#A31515;">&#39;./ZipCodeValidator&#39;</span>);
<span style="color:Blue;">import</span> letters = require(<span style="color:#A31515;">&#39;./LettersOnlyValidator&#39;</span>);
<span style="color:Green;">// Some samples to try</span>
<span style="color:Blue;">var</span> strings = [<span style="color:#A31515;">&#39;Hello&#39;</span>, <span style="color:#A31515;">&#39;98052&#39;</span>, <span style="color:#A31515;">&#39;101&#39;</span>];
<span style="color:Green;">// Validators to use</span>
<span style="color:Blue;">var</span> validators: { [s: string]: validation.StringValidator; } = {};
validators[<span style="color:#A31515;">&#39;ZIP code&#39;</span>] = <span style="color:Blue;">new</span> zip.ZipCodeValidator();
validators[<span style="color:#A31515;">&#39;Letters only&#39;</span>] = <span style="color:Blue;">new</span> letters.LettersOnlyValidator();
<span style="color:Green;">// Show whether each string passed each validator</span>
strings.forEach(s =&gt; {
<span style="color:Blue;">for</span> (<span style="color:Blue;">var</span> name <span style="color:Blue;">in</span> validators) {
console.log(<span style="color:#A31515;">&#39;&quot;&#39;</span> + s + <span style="color:#A31515;">&#39;&quot; &#39;</span> + (validators[name].isAcceptable(s) ? <span style="color:#A31515;">&#39; matches &#39;</span> : <span style="color:#A31515;">&#39; does not match &#39;</span>) + name);
}
});
</pre></div>
<h3>Code Generation for External Modules</h3>
Depending on the module target specified during compilation, the compiler will generate appropriate code for either node.js (commonjs) or require.js (AMD) module-loading systems. For more information on what the <i>define</i> and <i>require</i> calls in the generated code do, consult the documentation for each module loader.<br /><br />This simple example shows how the names used during importing and exporting get translated into the module loading code.<br />
<h5>SimpleModule.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">import</span> m = require(<span style="color:#A31515;">&#39;mod&#39;</span>);
<span style="color:Blue;">export</span> <span style="color:Blue;">var</span> t = m.something + 1;
</pre></div>
<h5>AMD / RequireJS SimpleModule.js:</h5>
<div style="color:Black;background-color:White;"><pre>
define([<span style="color:#A31515;">&quot;require&quot;</span>, <span style="color:#A31515;">&quot;exports&quot;</span>, <span style="color:#A31515;">&#39;mod&#39;</span>], <span style="color:Blue;">function</span>(require, exports, m) {
exports.t = m.something + 1;
});
</pre></div>
<h5>CommonJS / Node SimpleModule.js:</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> m = require(<span style="color:#A31515;">&#39;mod&#39;</span>);
exports.t = m.something + 1;
</pre></div>
<h1>Export =</h1>
In the previous example, when we consumed each validator, each module only exported one value. In cases like this, it&#39;s cumbersome to work with these symbols through their qualified name when a single identifier would do just as well.<br /><br />The export = syntax specifies a single object that is exported from the module. This can be a class, interface, module, function, or enum. When imported, the exported symbol is consumed directly and is not qualified by any name.<br /><br />Below, we&#39;ve simplified the Validator implementations to only export a single object from each module using the export = syntax. This simplifies the consumption code – instead of referring to &#39;zip.ZipCodeValidator&#39;, we can simply refer to &#39;zipValidator&#39;.<br />
<h5>Validation.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">export</span> <span style="color:Blue;">interface</span> StringValidator {
isAcceptable(s: string): <span style="color:Blue;">boolean</span>;
}
</pre></div>
<h5>LettersOnlyValidator.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">import</span> validation = require(<span style="color:#A31515;">&#39;./Validation&#39;</span>);
<span style="color:Blue;">var</span> lettersRegexp = /^[A-Za-z]+$/;
<span style="color:Blue;">class</span> LettersOnlyValidator <span style="color:Blue;">implements</span> validation.StringValidator {
isAcceptable(s: string) {
<span style="color:Blue;">return</span> lettersRegexp.test(s);
}
}
<span style="color:Blue;">export</span> = LettersOnlyValidator;
</pre></div>
<h5>ZipCodeValidator.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">import</span> validation = require(<span style="color:#A31515;">&#39;./Validation&#39;</span>);
<span style="color:Blue;">var</span> numberRegexp = /^[0-9]+$/;
<span style="color:Blue;">class</span> ZipCodeValidator <span style="color:Blue;">implements</span> validation.StringValidator {
isAcceptable(s: string) {
<span style="color:Blue;">return</span> s.length === 5 &amp;&amp; numberRegexp.test(s);
}
}
<span style="color:Blue;">export</span> = ZipCodeValidator;
</pre></div>
<h5>Test.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">import</span> validation = require(<span style="color:#A31515;">&#39;./Validation&#39;</span>);
<span style="color:Blue;">import</span> zipValidator = require(<span style="color:#A31515;">&#39;./ZipCodeValidator&#39;</span>);
<span style="color:Blue;">import</span> lettersValidator = require(<span style="color:#A31515;">&#39;./LettersOnlyValidator&#39;</span>);
<span style="color:Green;">// Some samples to try</span>
<span style="color:Blue;">var</span> strings = [<span style="color:#A31515;">&#39;Hello&#39;</span>, <span style="color:#A31515;">&#39;98052&#39;</span>, <span style="color:#A31515;">&#39;101&#39;</span>];
<span style="color:Green;">// Validators to use</span>
<span style="color:Blue;">var</span> validators: { [s: string]: validation.StringValidator; } = {};
validators[<span style="color:#A31515;">&#39;ZIP code&#39;</span>] = <span style="color:Blue;">new</span> zipValidator();
validators[<span style="color:#A31515;">&#39;Letters only&#39;</span>] = <span style="color:Blue;">new</span> lettersValidator();
<span style="color:Green;">// Show whether each string passed each validator</span>
strings.forEach(s =&gt; {
<span style="color:Blue;">for</span> (<span style="color:Blue;">var</span> name <span style="color:Blue;">in</span> validators) {
console.log(<span style="color:#A31515;">&#39;&quot;&#39;</span> + s + <span style="color:#A31515;">&#39;&quot; &#39;</span> + (validators[name].isAcceptable(s) ? <span style="color:#A31515;">&#39; matches &#39;</span> : <span style="color:#A31515;">&#39; does not match &#39;</span>) + name);
}
});
</pre></div>
<h1>Alias</h1>
Another way that you can simplify working with either kind of module is to use <i>import q = x.y.z</i> to create shorter names for commonly-used objects. Not to be confused with the <i>import x = require(&#39;name&#39;)</i> syntax used to load external modules, this syntax simply creates an alias for the specified symbol. You can use these sorts of imports (commonly referred to as aliases) for any kind of identifier, including objects created from external module imports.<br />
<h5>Basic Aliasing</h5>
<div style="color:Black;background-color:White;"><pre>
module Shapes {
<span style="color:Blue;">export</span> module Polygons {
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> Triangle { }
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> Square { }
}
}
<span style="color:Blue;">import</span> polygons = Shapes.Polygons;
<span style="color:Blue;">var</span> sq = <span style="color:Blue;">new</span> polygons.Square(); <span style="color:Green;">// Same as &#39;new Shapes.Polygons.Square()&#39;</span>
</pre></div><br />Notice that we don&#39;t use the <i>require</i> keyword; instead we assign directly from the qualified name of the symbol we&#39;re importing. This is similar to using <i>var</i>, but also works on the type and namespace meanings of the imported symbol. Importantly, for values, <i>import</i> is a distinct reference from the original symbol, so changes to an aliased <i>var</i> will not be reflected in the original variable.<br />
<h1>Optional Module Loading and Other Advanced Loading Scenarios</h1>
In some cases, you may want to only load a module under some conditions. In TypeScript, we can use the pattern shown below to implement this and other advanced loading scenarios to directly invoke the module loaders without losing type safety.<br /><br />The compiler detects whether each module is used in the emitted JavaScript. For modules that are only used as part of the type system, no require calls are emitted. This culling of unused references is a good performance optimization, and also allows for optional loading of those modules.<br /><br />The core idea of the pattern is that the <i>import id = require(&#39;...&#39;)</i> statement gives us access to the types exposed by the external module. The module loader is invoked (through require) dynamically, as shown in the if blocks below. This leverages the reference-culling optimization so that the module is only loaded when needed. For this pattern to work, it&#39;s important that the symbol defined via import is only used in type positions (i.e. never in a position that would be emitted into the JavaScript).<br /><br />To maintain type safety, we can use the <i>typeof</i> keyword. The <i>typeof</i> keyword, when used in a type position, produces the type of a value, in this case the type of the external module.<br />
<h5>Dynamic Module Loading in node.js</h5>
<div style="color:Black;background-color:White;"><pre>
declare <span style="color:Blue;">var</span> require;
<span style="color:Blue;">import</span> Zip = require(<span style="color:#A31515;">&#39;./ZipCodeValidator&#39;</span>);
<span style="color:Blue;">if</span> (needZipValidation) {
<span style="color:Blue;">var</span> x: <span style="color:Blue;">typeof</span> Zip = require(<span style="color:#A31515;">&#39;./ZipCodeValidator&#39;</span>);
<span style="color:Blue;">if</span> (x.isAcceptable(<span style="color:#A31515;">&#39;.....&#39;</span>)) { <span style="color:Green;">/* ... */</span> }
}
</pre></div>
<h5>Sample: Dynamic Module Loading in require.js</h5>
<div style="color:Black;background-color:White;"><pre>
declare <span style="color:Blue;">var</span> require;
<span style="color:Blue;">import</span> Zip = require(<span style="color:#A31515;">&#39;./ZipCodeValidator&#39;</span>);
<span style="color:Blue;">if</span> (needZipValidation) {
require([<span style="color:#A31515;">&#39;./ZipCodeValidator&#39;</span>], (x: <span style="color:Blue;">typeof</span> Zip) =&gt; {
<span style="color:Blue;">if</span> (x.isAcceptable(<span style="color:#A31515;">&#39;...&#39;</span>)) { <span style="color:Green;">/* ... */</span> }
});
}
</pre></div>
<h1>Working with Other JavaScript Libraries</h1>
To describe the shape of libraries not written in TypeScript, we need to declare the API that the library exposes. Because most JavaScript libraries expose only a few top-level objects, modules are a good way to represent them. We call declarations that don&#39;t define an implementation &quot;ambient&quot;. Typically these are defined in .d.ts files. If you&#39;re familiar with C/C++, you can think of these as .h files or &#39;extern&#39;. Let&#39;s look at a few examples with both internal and external examples.<br />
<h3>Ambient Internal Modules</h3>
The popular library D3 defines its functionality in a global object called &#39;D3&#39;. Because this library is loaded through a <i>script</i> tag (instead of a module loader), its declaration uses internal modules to define its shape. For the TypeScript compiler to see this shape, we use an ambient internal module declaration. For example:<br />
<h5>D3.d.ts (simplified excerpt)</h5>
<div style="color:Black;background-color:White;"><pre>
declare module D3 {
<span style="color:Blue;">export</span> <span style="color:Blue;">interface</span> Selectors {
select: {
(selector: string): Selection;
(element: EventTarget): Selection;
};
}
<span style="color:Blue;">export</span> <span style="color:Blue;">interface</span> Event {
x: number;
y: number;
}
<span style="color:Blue;">export</span> <span style="color:Blue;">interface</span> Base <span style="color:Blue;">extends</span> Selectors {
event: Event;
}
}
declare <span style="color:Blue;">var</span> d3: D3.Base;
</pre></div>
<h3>Ambient External Modules</h3>
In node.js, most tasks are accomplished by loading one or more modules. We could define each module in its own .d.ts file with top-level export declarations, but it&#39;s more convenient to write them as one larger .d.ts file. To do so, we use the quoted name of the module, which will be available to a later import. For example:<br />
<h5>node.d.ts (simplified excerpt)</h5>
<div style="color:Black;background-color:White;"><pre>
declare module <span style="color:#A31515;">&quot;url&quot;</span> {
<span style="color:Blue;">export</span> <span style="color:Blue;">interface</span> Url {
protocol?: string;
hostname?: string;
pathname?: string;
}
<span style="color:Blue;">export</span> <span style="color:Blue;">function</span> parse(urlStr: string, parseQueryString?, slashesDenoteHost?): Url;
}
declare module <span style="color:#A31515;">&quot;path&quot;</span> {
<span style="color:Blue;">export</span> <span style="color:Blue;">function</span> normalize(p: string): string;
<span style="color:Blue;">export</span> <span style="color:Blue;">function</span> join(...paths: any[]): string;
<span style="color:Blue;">export</span> <span style="color:Blue;">var</span> sep: string;
}
</pre></div><br />Now we can <i>/// &lt;reference&gt;</i> node.d.ts and then load the modules using e.g. <i>import url = require(&#39;url&#39;);</i>.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">///&lt;reference path=&quot;node.d.ts&quot;/&gt;</span>
<span style="color:Blue;">import</span> url = require(<span style="color:#A31515;">&quot;url&quot;</span>);
<span style="color:Blue;">var</span> myUrl = url.parse(<span style="color:#A31515;">&quot;http://www.typescriptlang.org&quot;</span>);
</pre></div><br />
<h1>Pitfalls of Modules</h1>
In this section we&#39;ll describe various common pitfalls in using internal and external modules, and how to avoid them.<br />
<h3>/// &lt;reference&gt; to an external module</h3>
A common mistake is to try to use the /// &lt;reference&gt; syntax to refer to an external module file, rather than using import. To understand the distinction, we first need to understand the three ways that the compiler can locate the type information for an external module.<br /><br />The first is by finding a .ts file named by an <i>import x = require(...);</i> declaration. That file should be an implementation file with top-level import or export declarations.<br /><br />The second is by finding a .d.ts file, similar to above, except that instead of being an implementation file, it&#39;s a declaration file (also with top-level import or export declarations).<br /><br />The final way is by seeing an &quot;ambient external module declaration&quot;, where we &#39;declare&#39; a module with a matching quoted name.<br />
<h5>myModules.d.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">// In a .d.ts file or .ts file that is not an external module:</span>
declare module <span style="color:#A31515;">&quot;SomeModule&quot;</span> {
<span style="color:Blue;">export</span> <span style="color:Blue;">function</span> fn(): string;
}
</pre></div>
<h5>myOtherModule.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Green;">/// &lt;reference path=&quot;myModules.d.ts&quot; /&gt;</span>
<span style="color:Blue;">import</span> m = require(<span style="color:#A31515;">&quot;SomeModule&quot;</span>);
</pre></div><br />The reference tag here allows us to locate the declaration file that contains the declaration for the ambient external module. This is how the node.d.ts file that several of the TypeScript samples use is consumed, for example.<br />
<h3>Needless Namespacing</h3>
If you&#39;re converting a program from internal modules to external modules, it can be easy to end up with a file that looks like this:<br />
<h5>shapes.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">export</span> module Shapes {
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> Triangle { <span style="color:Green;">/* ... */</span> }
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> Square { <span style="color:Green;">/* ... */</span> }
}
</pre></div><br />The top-level module here <i>Shapes</i> wraps up <i>Triangle</i> and <i>Square</i> for no reason. This is confusing and annoying for consumers of your module:
<h5>shapeConsumer.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">import</span> shapes = require(<span style="color:#A31515;">&#39;./shapes&#39;</span>);
<span style="color:Blue;">var</span> t = <span style="color:Blue;">new</span> shapes.Shapes.Triangle(); <span style="color:Green;">// shapes.Shapes?</span>
</pre></div><br />A key feature of external modules in TypeScript is that two different external modules will never contribute names to the same scope. Because the consumer of an external module decides what name to assign it, there&#39;s no need to proactively wrap up the exported symbols in a namespace.<br /><br />To reiterate why you shouldn&#39;t try to namespace your external module contents, the general idea of namespacing is to provide logical grouping of constructs and to prevent name collisions. Because the external module file itself is already a logical grouping, and its top-level name is defined by the code that imports it, it&#39;s unnecessary to use an additional module layer for exported objects.<br /> <br />Revised Example:
<h5>shapes.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> Triangle { <span style="color:Green;">/* ... */</span> }
<span style="color:Blue;">export</span> <span style="color:Blue;">class</span> Square { <span style="color:Green;">/* ... */</span> }
</pre></div>
<h5>shapeConsumer.ts</h5>
<div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">import</span> shapes = require(<span style="color:#A31515;">&#39;./shapes&#39;</span>);
<span style="color:Blue;">var</span> t = <span style="color:Blue;">new</span> shapes.Triangle();
</pre></div>
<h3>Trade-offs for External Modules</h3>
Just as there is a one-to-one correspondence between JS files and modules, TypeScript has a one-to-one correspondence between external module source files and their emitted JS files. One effect of this is that it&#39;s not possible to use the <i>--out</i> compiler switch to concatenate multiple external module source files into a single JavaScript file.</div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:36:44 GMTUpdated Wiki: Modules in TypeScript 20141103043644PUpdated Wiki: Classes in TypeScripthttps://typescript.codeplex.com/wikipage?title=Classes in TypeScript&version=12<div class="wikidoc"><i><b>Please note:</b> This page is a work-in-progress. It may have errors and is subject to change.</i><br />
<hr />
<h1>Introduction</h1>
Traditional JavaScript focuses on functions and prototype-based inheritance as the basic means of building up reusable components, but this may feel a bit awkward to programmers more comfortable with an object-oriented approach, where classes inherit functionality and objects are built from these classes. Starting with ECMAScript 6, the next version of JavaScript, JavaScript programmers will be able to build their applications using this object-oriented class-based approach. In TypeScript, we allow developers to use these techniques now, and compile them down to JavaScript that works across all major browsers and platforms, without having to wait for the next version of JavaScript.<br />
<h1>Classes</h1>
Let&#39;s take a look at a simple class-based example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Greeter {
greeting: string;
constructor(message: string) {
<span style="color:Blue;">this</span>.greeting = message;
}
greet() {
<span style="color:Blue;">return</span> <span style="color:#A31515;">&quot;Hello, &quot;</span> + <span style="color:Blue;">this</span>.greeting;
}
}
<span style="color:Blue;">var</span> greeter = <span style="color:Blue;">new</span> Greeter(<span style="color:#A31515;">&quot;world&quot;</span>);
</pre></div><br />The syntax should look very familiar if you&#39;ve used C# or Java before. We declare a new class &#39;Greeter&#39;. This class has three members, a property called &#39;greeting&#39;, a constructor, and a method &#39;greet&#39;. <br /><br />You&#39;ll notice that in the class when we refer to one of the members of the class we prepend &#39;this.&#39;. This denotes that it&#39;s a member access.<br /><br />In the last line we construct an instance of the Greeter class using &#39;new&#39;. This calls into the constructor we defined earlier, creating a new object with the Greeter shape, and running the constructor to initialize it.<br />
<h1>Inheritance</h1>
In TypeScript, we can use common object-oriented patterns. Of course, one of the most fundamental patterns in class-based programming is being able to extend existing classes to create new ones using inheritance.<br /><br />Let&#39;s take a look at an example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Animal {
name:string;
constructor(theName: string) { <span style="color:Blue;">this</span>.name = theName; }
move(meters: number) {
alert(<span style="color:Blue;">this</span>.name + <span style="color:#A31515;">&quot; moved &quot;</span> + meters + <span style="color:#A31515;">&quot;m.&quot;</span>);
}
}
<span style="color:Blue;">class</span> Snake <span style="color:Blue;">extends</span> Animal {
constructor(name: string) { <span style="color:Blue;">super</span>(name); }
move() {
alert(<span style="color:#A31515;">&quot;Slithering...&quot;</span>);
<span style="color:Blue;">super</span>.move(5);
}
}
<span style="color:Blue;">class</span> Horse <span style="color:Blue;">extends</span> Animal {
constructor(name: string) { <span style="color:Blue;">super</span>(name); }
move() {
alert(<span style="color:#A31515;">&quot;Galloping...&quot;</span>);
<span style="color:Blue;">super</span>.move(45);
}
}
<span style="color:Blue;">var</span> sam = <span style="color:Blue;">new</span> Snake(<span style="color:#A31515;">&quot;Sammy the Python&quot;</span>);
<span style="color:Blue;">var</span> tom: Animal = <span style="color:Blue;">new</span> Horse(<span style="color:#A31515;">&quot;Tommy the Palomino&quot;</span>);
sam.move();
tom.move(34);
</pre></div><br />This example covers quite a bit of the inheritance features in TypeScript that are common to other languages. Here we see using the &#39;extends&#39; keywords to create a subclass. You can see this where &#39;Horse&#39; and &#39;Snake&#39; subclass the base class &#39;Animal&#39; and gain access to its features.<br /><br />The example also shows off being able to override methods in the base class with methods that are specialized for the subclass. Here both &#39;Snake&#39; and &#39;Horse&#39; create a &#39;move&#39; method that overrides the &#39;move&#39; from &#39;Animal&#39;, giving it functionality specific to each class.<br />
<h1>Private/Public modifiers</h1>
<h2>Public by default</h2>
You may have noticed in the above examples we haven&#39;t had to use the word &#39;public&#39; to make any of the members of the class visible. Languages like C# require that each member be explicitly labelled &#39;public&#39; to be visible. In TypeScript, each member is public by default. <br /><br />You may still mark members a private, so you control what is publicly visible outside of your class. We could have written the &#39;Animal&#39; class from the previous section like so:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Animal {
<span style="color:Blue;">private</span> name:string;
constructor(theName: string) { <span style="color:Blue;">this</span>.name = theName; }
move(meters: number) {
alert(<span style="color:Blue;">this</span>.name + <span style="color:#A31515;">&quot; moved &quot;</span> + meters + <span style="color:#A31515;">&quot;m.&quot;</span>);
}
}
</pre></div>
<h2>Understanding private</h2>
TypeScript is a structural type system. When we compare two different types, regardless of where they came from, if the types of each member are compatible, then we say the types themselves are compatible. <br /><br />When comparing types that have &#39;private&#39; members, we treat these differently. For two types to be considered compatible, if one of them has a private member, then the other must have a private member that originated in the same declaration. <br /><br />Let&#39;s look at an example to better see how this plays out in practice:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Animal {
<span style="color:Blue;">private</span> name:string;
constructor(theName: string) { <span style="color:Blue;">this</span>.name = theName; }
}
<span style="color:Blue;">class</span> Rhino <span style="color:Blue;">extends</span> Animal {
constructor() { <span style="color:Blue;">super</span>(<span style="color:#A31515;">&quot;Rhino&quot;</span>); }
}
<span style="color:Blue;">class</span> Employee {
<span style="color:Blue;">private</span> name:string;
constructor(theName: string) { <span style="color:Blue;">this</span>.name = theName; }
}
<span style="color:Blue;">var</span> animal = <span style="color:Blue;">new</span> Animal(<span style="color:#A31515;">&quot;Goat&quot;</span>);
<span style="color:Blue;">var</span> rhino = <span style="color:Blue;">new</span> Rhino();
<span style="color:Blue;">var</span> employee = <span style="color:Blue;">new</span> Employee(<span style="color:#A31515;">&quot;Bob&quot;</span>);
animal = rhino;
animal = employee; <span style="color:Green;">//error: Animal and Employee are not compatible</span>
</pre></div><br />In this example, we have an &#39;Animal&#39; and a &#39;Rhino&#39;, with &#39;Rhino&#39; being a subclass of &#39;Animal&#39;. We also have a new class &#39;Employee&#39; that looks identical to &#39;Animal&#39; in terms of shape. We create some instances of these classes and then try to assign them to each other to see what will happen. Because &#39;Animal&#39; and &#39;Rhino&#39; share the private side of their shape from the same declaration of &#39;private name: string&#39; in &#39;Animal&#39;, they are compatible. However, this is not the case for &#39;Employee&#39;. When we try to assign from an &#39;Employee&#39; to &#39;Animal&#39; we get an error that these types are not compatible. Even though &#39;Employee&#39; also has a private member called &#39;name&#39;, it is not the same one as the one created in &#39;Animal&#39;. <br />
<h2>Parameter properties</h2>
The keywords &#39;public&#39; and &#39;private&#39; also give you a shorthand for creating and initializing members of your class, by creating parameter properties. The properties let you can create and initialize a member in one step. Here&#39;s a further revision of the previous example. Notice how we drop &#39;theName&#39; altogether and just use the shortened &#39;private name: string&#39; parameter on the constructor to create and initialize the &#39;name&#39; member.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Animal {
constructor(<span style="color:Blue;">private</span> name: string) { }
move(meters: number) {
alert(<span style="color:Blue;">this</span>.name + <span style="color:#A31515;">&quot; moved &quot;</span> + meters + <span style="color:#A31515;">&quot;m.&quot;</span>);
}
}
</pre></div><br />Using &#39;private&#39; in this way creates and initializes a private member, and similarly for &#39;public&#39;. <br />
<h1>Accessors</h1>
TypeScript supports getters/setters as a way of intercepting accesses to a member of an object. This gives you a way of having finer-grained control over how a member is accessed on each object.<br /><br />Let&#39;s convert a simple class to use &#39;get&#39; and &#39;set&#39;. First, let&#39;s start with an example without getters and setters.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Employee {
fullName: string;
}
<span style="color:Blue;">var</span> employee = <span style="color:Blue;">new</span> Employee();
employee.fullName = <span style="color:#A31515;">&quot;Bob Smith&quot;</span>;
<span style="color:Blue;">if</span> (employee.fullName) {
alert(employee.fullName);
}
</pre></div><br />While allowing people to randomly set fullName directly is pretty handy, this might get us in trouble if we people can change names on a whim. <br /><br />In this version, we check to make sure the user has a secret passcode available before we allow them to modify the employee. We do this by replacing the direct access to fullName with a &#39;set&#39; that will check the passcode. We add a corresponding &#39;get&#39; to allow the previous example to continue to work seamlessly.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> passcode = <span style="color:#A31515;">&quot;secret passcode&quot;</span>;
<span style="color:Blue;">class</span> Employee {
<span style="color:Blue;">private</span> _fullName: string;
get fullName(): string {
<span style="color:Blue;">return</span> <span style="color:Blue;">this</span>._fullName;
}
set fullName(newName: string) {
<span style="color:Blue;">if</span> (passcode &amp;&amp; passcode == <span style="color:#A31515;">&quot;secret passcode&quot;</span>) {
<span style="color:Blue;">this</span>._fullName = newName;
}
<span style="color:Blue;">else</span> {
alert(<span style="color:#A31515;">&quot;Error: Unauthorized update of employee!&quot;</span>);
}
}
}
<span style="color:Blue;">var</span> employee = <span style="color:Blue;">new</span> Employee();
employee.fullName = <span style="color:#A31515;">&quot;Bob Smith&quot;</span>;
<span style="color:Blue;">if</span> (employee.fullName) {
alert(employee.fullName);
}
</pre></div><br />To prove to ourselves that our accessor is now checking the passcode, we can modify the passcode and see that when it doesn&#39;t match we instead get the alert box warning us we don&#39;t have access to update the employee.<br /><br />Note: Accessors require you to set the compiler to output ECMAScript 5.<br />
<h1>Static Properties</h1>
Up to this point, we&#39;ve only talked about the <i>instance</i> members of the class, those that show up on the object when its instantiated. We can also create <i>static</i> members of a class, those that are visible on the class itself rather than on the instances. In this example, we use &#39;static&#39; on the origin, as it&#39;s a general value for all grids. Each instance accesses this value through prepending the name of the class. Similarly to prepending &#39;this.&#39; in front of instance accesses, here we prepend &#39;Grid.&#39; in front of static accesses.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Grid {
<span style="color:Blue;">static</span> origin = {x: 0, y: 0};
calculateDistanceFromOrigin(point: {x: number; y: number;}) {
<span style="color:Blue;">var</span> xDist = (point.x - Grid.origin.x);
<span style="color:Blue;">var</span> yDist = (point.y - Grid.origin.y);
<span style="color:Blue;">return</span> Math.sqrt(xDist * xDist + yDist * yDist) / <span style="color:Blue;">this</span>.scale;
}
constructor (<span style="color:Blue;">public</span> scale: number) { }
}
<span style="color:Blue;">var</span> grid1 = <span style="color:Blue;">new</span> Grid(1.0); <span style="color:Green;">// 1x scale</span>
<span style="color:Blue;">var</span> grid2 = <span style="color:Blue;">new</span> Grid(5.0); <span style="color:Green;">// 5x scale</span>
alert(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
alert(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
</pre></div>
<h1>Advanced Techniques</h1>
<h2>Constructor functions</h2>
When you declare a class in TypeScript, you are actually creating multiple declarations at the same time. The first is the type of the <i>instance</i> of the class.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Greeter {
greeting: string;
constructor(message: string) {
<span style="color:Blue;">this</span>.greeting = message;
}
greet() {
<span style="color:Blue;">return</span> <span style="color:#A31515;">&quot;Hello, &quot;</span> + <span style="color:Blue;">this</span>.greeting;
}
}
<span style="color:Blue;">var</span> greeter: Greeter;
greeter = <span style="color:Blue;">new</span> Greeter(<span style="color:#A31515;">&quot;world&quot;</span>);
alert(greeter.greet());
</pre></div><br />Here, when we say &#39;var greeter: Greeter&#39;, we&#39;re using Greeter as the type of instances of the class Greeter. This is almost second nature to programmers from other object-oriented languages. <br /> <br />We&#39;re also creating another value that we call the <i>constructor function</i>. This is the function that is called when we &#39;new&#39; up instances of the class. To see what this looks like in practice, let&#39;s take a look at the JavaScript created by the above example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> Greeter = (<span style="color:Blue;">function</span> () {
<span style="color:Blue;">function</span> Greeter(message) {
<span style="color:Blue;">this</span>.greeting = message;
}
Greeter.prototype.greet = <span style="color:Blue;">function</span> () {
<span style="color:Blue;">return</span> <span style="color:#A31515;">&quot;Hello, &quot;</span> + <span style="color:Blue;">this</span>.greeting;
};
<span style="color:Blue;">return</span> Greeter;
})();
<span style="color:Blue;">var</span> greeter;
greeter = <span style="color:Blue;">new</span> Greeter(<span style="color:#A31515;">&quot;world&quot;</span>);
alert(greeter.greet());
</pre></div><br />Here, &#39;var Greeter&#39; is going to be assigned the constructor function. When we call &#39;new&#39; and run this function, we get an instance of the class. The constructor function also contains all of the static members of the class. Another way to think of each class is that there is an <i>instance</i> side and a <i>static</i> side.<br /><br />Let&#39;s modify the example a bit to show this difference:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Greeter {
<span style="color:Blue;">static</span> standardGreeting = <span style="color:#A31515;">&quot;Hello, there&quot;</span>;
greeting: string;
greet() {
<span style="color:Blue;">if</span> (<span style="color:Blue;">this</span>.greeting) {
<span style="color:Blue;">return</span> <span style="color:#A31515;">&quot;Hello, &quot;</span> + <span style="color:Blue;">this</span>.greeting;
}
<span style="color:Blue;">else</span> {
<span style="color:Blue;">return</span> Greeter.standardGreeting;
}
}
}
<span style="color:Blue;">var</span> greeter1: Greeter;
greeter1 = <span style="color:Blue;">new</span> Greeter();
alert(greeter1.greet());
<span style="color:Blue;">var</span> greeterMaker: <span style="color:Blue;">typeof</span> Greeter = Greeter;
greeterMaker.standardGreeting = <span style="color:#A31515;">&quot;Hey there!&quot;</span>;
<span style="color:Blue;">var</span> greeter2:Greeter = <span style="color:Blue;">new</span> greeterMaker();
alert(greeter2.greet());
</pre></div><br />In this example, &#39;greeter1&#39; works similarly to before. We instantiate the &#39;Greeter&#39; class, and use this object. This we have seen before.<br /><br />Next, we then use the class directly. Here we create a new variable called &#39;greeterMaker&#39;. This variable will hold the class itself, or said another way its constructor function. Here we use &#39;typeof Greeter&#39;, that is &quot;give me the type of the Greeter class itself&quot; rather than the instance type. Or, more precisely, &quot;give me the type of the symbol called Greeter&quot;, which is the type of the constructor function. This type will contain all of the static members of Greeter along with the constructor that creates instances of the Greeter class. We show this by using &#39;new&#39; on &#39;greeterMaker&#39;, creating new instances of &#39;Greeter&#39; and invoking them as before.<br />
<h2>Using a class as an interface</h2>
As we said in the previous section, a class declaration creates two things: a type representing instances of the class and a constructor function. Because classes create types, you can use them in the same places you would be able to use interfaces.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">class</span> Point {
x: number;
y: number;
}
<span style="color:Blue;">interface</span> Point3d <span style="color:Blue;">extends</span> Point {
z: number;
}
<span style="color:Blue;">var</span> point3d: Point3d = {x: 1, y: 2, z: 3};
</pre></div><br /></div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:34:56 GMTUpdated Wiki: Classes in TypeScript 20141103043456PUpdated Wiki: Interfaces in TypeScripthttps://typescript.codeplex.com/wikipage?title=Interfaces in TypeScript&version=17<div class="wikidoc"><i><b>Please note:</b> This page is a work-in-progress. It may have errors and is subject to change.</i><br />
<hr />
<h1>Introduction</h1>
One of TypeScript&#39;s core principles is that type-checking focuses on the &#39;shape&#39; that values have. This is sometimes called &quot;duck typing&quot; or &quot;structural subtyping&quot;. In TypeScript, interfaces fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project. <br />
<h1>Our First Interface </h1>
The easiest way to see how interfaces work is to start with a simple example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> printLabel(labelledObj: {label: string}) {
console.log(labelledObj.label);
}
<span style="color:Blue;">var</span> myObj = {size: 10, label: <span style="color:#A31515;">&quot;Size 10 Object&quot;</span>};
printLabel(myObj);
</pre></div><br />The type-checker checks the call to &#39;printLabel&#39;. The &#39;printLabel&#39; function has a single parameter that requires that the object passed in has a property called &#39;label&#39; of type string. Notice that our object actually has more properties than this, but the compiler only checks to that <i>at least</i> the ones required are present and match the types required. <br /><br />We can write the same example again, this time using an interface to describe the requirement of having the &#39;label&#39; property that is a string:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> LabelledValue {
label: string;
}
<span style="color:Blue;">function</span> printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}
<span style="color:Blue;">var</span> myObj = {size: 10, label: <span style="color:#A31515;">&quot;Size 10 Object&quot;</span>};
printLabel(myObj);
</pre></div><br />The interface &#39;LabelledValue&#39; is a name we can now use to describe the requirement in the previous example. It still represents having a single property called &#39;label&#39; that is of type string. Notice we didn&#39;t have to explicitly say that the object we pass to &#39;printLabel&#39; implements this interface like we might have to in other languages. Here, it&#39;s only the shape that matters. If the object we pass to the function meets the requirements listed, then it&#39;s allowed.<br /><br />It&#39;s worth pointing out that the type-checker does not require that these properties come in any sort of order, only that the properties the interface requires are present and have the required type.<br />
<h1>Optional Properties</h1>
Not all properties of an interface may be required. Some exist under certain conditions or may not be there at all. These optional properties are popular when creating patterns like &quot;option bags&quot; where the user passes an object to a function that only has a couple properties filled in.<br /><br />Here&#39;s as example of this pattern:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SquareConfig {
color?: string;
width?: number;
}
<span style="color:Blue;">function</span> createSquare(config: SquareConfig): {color: string; area: number} {
<span style="color:Blue;">var</span> newSquare = {color: <span style="color:#A31515;">&quot;white&quot;</span>, area: 100};
<span style="color:Blue;">if</span> (config.color) {
newSquare.color = config.color;
}
<span style="color:Blue;">if</span> (config.width) {
newSquare.area = config.width * config.width;
}
<span style="color:Blue;">return</span> newSquare;
}
<span style="color:Blue;">var</span> mySquare = createSquare({color: <span style="color:#A31515;">&quot;black&quot;</span>});
</pre></div><br />Interfaces with optional properties are written similar to other interfaces, which each optional property denoted with a &#39;?&#39; as part of the property declaration. <br /><br />The advantage of optional properties is that you can describe these possibly available properties while still also catching properties that you know are not expected to be available. For example, had we mistyped the name of the property we passed to &#39;createSquare&#39;, we would get an error message letting us know:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SquareConfig {
color?: string;
width?: number;
}
<span style="color:Blue;">function</span> createSquare(config: SquareConfig): {color: string; area: number} {
<span style="color:Blue;">var</span> newSquare = {color: <span style="color:#A31515;">&quot;white&quot;</span>, area: 100};
<span style="color:Blue;">if</span> (config.color) {
newSquare.color = config.collor; <span style="color:Green;">// Type-checker can catch the mistyped name here</span>
}
<span style="color:Blue;">if</span> (config.width) {
newSquare.area = config.width * config.width;
}
<span style="color:Blue;">return</span> newSquare;
}
<span style="color:Blue;">var</span> mySquare = createSquare({color: <span style="color:#A31515;">&quot;black&quot;</span>});
</pre></div>
<h1>Function Types</h1>
Interfaces are capable of describing the wide range of shapes that JavaScript objects can take. In addition to describing an object with properties, interfaces are also capable of describing function types.<br /><br />To describe a function type with an interface, we give the interface a call signature. This is like a function declaration with only the parameter list and return type given.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SearchFunc {
(source: string, subString: string): <span style="color:Blue;">boolean</span>;
}
</pre></div><br />Once defined, we can use this function type interface like we would other interfaces. Here, we show how you can create a variable of a function type and assign it a function value of the same type.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> mySearch: SearchFunc;
mySearch = <span style="color:Blue;">function</span>(source: string, subString: string) {
<span style="color:Blue;">var</span> result = source.search(subString);
<span style="color:Blue;">if</span> (result == -1) {
<span style="color:Blue;">return</span> <span style="color:Blue;">false</span>;
}
<span style="color:Blue;">else</span> {
<span style="color:Blue;">return</span> <span style="color:Blue;">true</span>;
}
}
</pre></div><br />For function types to correctly type-check, the name of the parameters do not need to match. We could have, for example, written the above example like this:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> mySearch: SearchFunc;
mySearch = <span style="color:Blue;">function</span>(src: string, sub: string) {
<span style="color:Blue;">var</span> result = src.search(sub);
<span style="color:Blue;">if</span> (result == -1) {
<span style="color:Blue;">return</span> <span style="color:Blue;">false</span>;
}
<span style="color:Blue;">else</span> {
<span style="color:Blue;">return</span> <span style="color:Blue;">true</span>;
}
}
</pre></div><br />Function parameters are checked one at a time, with the type in each corresponding parameter position checked against each other. Here, also, the return type of our function expression is implied by the values it returns (here <i>false</i> and <i>true</i>). Had the function expression returned numbers or strings, the type-checker would have warned us that return type doesn&#39;t match the return type described in the SearchFunc interface.<br />
<h1>Array Types</h1>
Similarly to how we can use interfaces to describe function types, we can also describe array types. Array types have an &#39;index&#39; type that describes the types allowed to index the object, along with the corresponding return type for accessing the index.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> StringArray {
[index: number]: string;
}
<span style="color:Blue;">var</span> myArray: StringArray;
myArray = [<span style="color:#A31515;">&quot;Bob&quot;</span>, <span style="color:#A31515;">&quot;Fred&quot;</span>];
</pre></div> <br />There are two types of supported index types: string and number. It is possible to support both types of index, with the restriction that the type returned from the numeric index must be a subtype of the type returned from the string index.<br /><br />While index signatures are a powerful way to describe the array and &#39;dictionary&#39; pattern, they also enforce that all properties match their return type. In this example, the property does not match the more general index, and the type-checker gives an error:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Dictionary {
[index: string]: string;
length: number; <span style="color:Green;">// error, the type of &#39;length&#39; is not a subtype of the indexer</span>
}
</pre></div>
<h1>Class Types</h1>
<h2>Implementing an interface</h2>
One of the most common uses of interfaces in languages like C# and Java, that of explicitly enforcing that a class meets a particular contract, is also possible in TypeScript.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockInterface {
currentTime: Date;
}
<span style="color:Blue;">class</span> Clock <span style="color:Blue;">implements</span> ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}
</pre></div><br />You can also describe methods in an interface that are implemented in the class, as we do with &#39;setTime&#39; in the below example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockInterface {
currentTime: Date;
setTime(d: Date);
}
<span style="color:Blue;">class</span> Clock <span style="color:Blue;">implements</span> ClockInterface {
currentTime: Date;
setTime(d: Date) {
<span style="color:Blue;">this</span>.currentTime = d;
}
constructor(h: number, m: number) { }
}
</pre></div><br />Interfaces describe the public side of the class, rather than both the public and private side. This prohibits you from using them to check that a class also has particular types for the private side of the class instance.<br />
<h2>Difference between static/instance side of class</h2>
When working with classes and interfaces, it helps to keep in mind that a class has <i>two</i> types: the type of the static side and the type of the instance side. You may notice that if you create an interface with a construct signature and try to create a class that implements this interface you get an error:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockInterface {
<span style="color:Blue;">new</span> (hour: number, minute: number);
}
<span style="color:Blue;">class</span> Clock <span style="color:Blue;">implements</span> ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}
</pre></div><br />This is because when a class implements an interface, only the instance side of the class is checked. Since the constructor sits in the static side, it is not included in this check.<br /><br />Instead, you would need to work with the &#39;static&#39; side of the class directly. In this example, we work with the class directly:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockStatic {
<span style="color:Blue;">new</span> (hour: number, minute: number);
}
<span style="color:Blue;">class</span> Clock {
currentTime: Date;
constructor(h: number, m: number) { }
}
<span style="color:Blue;">var</span> cs: ClockStatic = Clock;
<span style="color:Blue;">var</span> newClock = <span style="color:Blue;">new</span> cs(7, 30);
</pre></div>
<h1>Extending Interfaces</h1>
Like classes, interfaces can extend each other. This handles the task of copying the members of one interface into another, allowing you more freedom in how you separate your interfaces into reusable components.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Shape {
color: string;
}
<span style="color:Blue;">interface</span> Square <span style="color:Blue;">extends</span> Shape {
sideLength: number;
}
<span style="color:Blue;">var</span> square = &lt;Square&gt;{};
square.color = <span style="color:#A31515;">&quot;blue&quot;</span>;
square.sideLength = 10;
</pre></div><br />An interface can extend multiple interfaces, creating a combination of all of the interfaces.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Shape {
color: string;
}
<span style="color:Blue;">interface</span> PenStroke {
penWidth: number;
}
<span style="color:Blue;">interface</span> Square <span style="color:Blue;">extends</span> Shape, PenStroke {
sideLength: number;
}
<span style="color:Blue;">var</span> square = &lt;Square&gt;{};
square.color = <span style="color:#A31515;">&quot;blue&quot;</span>;
square.sideLength = 10;
square.penWidth = 5.0;
</pre></div>
<h1>Hybrid Types</h1>
As we mentioned earlier, interfaces can describe the rich types present in real world JavaScript. Because of JavaScript&#39;s dynamic and flexible nature, you may occasionally encounter an object that works as a combination of some of the types described above. <br /><br />One such example is an object that acts as both a function and an object, with additional properties:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Counter {
(start: number): string;
interval: number;
reset(): <span style="color:Blue;">void</span>;
}
<span style="color:Blue;">var</span> c: Counter;
c(10);
c.reset();
c.interval = 5.0;
</pre></div><br />When interacting with 3rd-party JavaScript, you may need to use patterns like the above to fully-describe the shape of the type.</div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:33:44 GMTUpdated Wiki: Interfaces in TypeScript 20141103043344PUpdated Wiki: Interfaces in TypeScripthttps://typescript.codeplex.com/wikipage?title=Interfaces in TypeScript&version=16<div class="wikidoc"><i><b>Please note:</b> This page is a work-in-progress. It may have errors and is subject to change.</i><br />
<hr />
<h1>Introduction</h1>
One of TypeScript&#39;s core principles is that type-checking focuses on the &#39;shape&#39; that values have. This is sometimes called &quot;duck typing&quot; or &quot;structural subtyping&quot;. In TypeScript, interfaces fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project. <br />
<h1>Our First Interface </h1>
The easiest way to see how interfaces work is to start with a simple example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> printLabel(labelledObj: {label: string}) {
console.log(labelledObj.label);
}
<span style="color:Blue;">var</span> myObj = {size: 10, label: <span style="color:#A31515;">&quot;Size 10 Object&quot;</span>};
printLabel(myObj);
</pre></div><br />The type-checker checks the call to &#39;printLabel&#39;. The &#39;printLabel&#39; function has a single parameter that requires that the object passed in has a property called &#39;label&#39; of type string. Notice that our object actually has more properties than this, but the compiler only checks to that <i>at least</i> the ones required are present and match the types required. <br /><br />We can write the same example again, this time using an interface to describe the requirement of having the &#39;label&#39; property that is a string:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> LabelledValue {
label: string;
}
<span style="color:Blue;">function</span> printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}
<span style="color:Blue;">var</span> myObj = {size: 10, label: <span style="color:#A31515;">&quot;Size 10 Object&quot;</span>};
printLabel(myObj);
</pre></div><br />The interface &#39;LabelledValue&#39; is a name we can now use to describe the requirement in the previous example. It still represents having a single property called &#39;label&#39; that is of type string. Notice we didn&#39;t have to explicitly say that the object we pass to &#39;printLabel&#39; implements this interface like we might have to in other languages. Here, it&#39;s only the shape that matters. If the object we pass to the function meets the requirements listed, then it&#39;s allowed.<br /><br />It&#39;s worth pointing out that the type-checker does not require that these properties come in any sort of order, only that the properties the interface requires are present and have the required type.<br />
<h1>Optional Properties</h1>
Not all properties of an interface may be required. Some exist under certain conditions or may not be there at all. These optional properties are popular when creating patterns like &quot;option bags&quot; where the user passes an object to a function that only has a couple properties filled in.<br /><br />Here&#39;s as example of this pattern:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SquareConfig {
color?: string;
width?: number;
}
<span style="color:Blue;">function</span> createSquare(config: SquareConfig): {color: string; area: number} {
<span style="color:Blue;">var</span> newSquare = {color: <span style="color:#A31515;">&quot;white&quot;</span>, area: 100};
<span style="color:Blue;">if</span> (config.color) {
newSquare.color = config.color;
}
<span style="color:Blue;">if</span> (config.width) {
newSquare.area = config.width * config.width;
}
<span style="color:Blue;">return</span> newSquare;
}
<span style="color:Blue;">var</span> mySquare = createSquare({color: <span style="color:#A31515;">&quot;black&quot;</span>});
</pre></div><br />Interfaces with optional properties are written similar to other interfaces, which each optional property denoted with a &#39;?&#39; as part of the property declaration. <br /><br />The advantage of optional properties is that you can describe these possibly available properties while still also catching properties that you know are not expected to be available. For example, had we mistyped the name of the property we passed to &#39;createSquare&#39;, we would get an error message letting us know:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SquareConfig {
color?: string;
width?: number;
}
<span style="color:Blue;">function</span> createSquare(config: SquareConfig): {color: string; area: number} {
<span style="color:Blue;">var</span> newSquare = {color: <span style="color:#A31515;">&quot;white&quot;</span>, area: 100};
<span style="color:Blue;">if</span> (config.color) {
newSquare.color = config.collor; <span style="color:Green;">// Type-checker can catch the mistyped name here</span>
}
<span style="color:Blue;">if</span> (config.width) {
newSquare.area = config.width * config.width;
}
<span style="color:Blue;">return</span> newSquare;
}
<span style="color:Blue;">var</span> mySquare = createSquare({color: <span style="color:#A31515;">&quot;black&quot;</span>});
</pre></div>
<h1>Function Types</h1>
Interfaces are capable of describing the wide range of shapes that JavaScript objects can take. In addition to describing an object with properties, interfaces are also capable of describing function types.<br /><br />To describe a function type with an interface, we give the interface a call signature. This is like a function declaration with only the parameter list and return type given.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SearchFunc {
(source: string, subString: string): <span style="color:Blue;">boolean</span>;
}
</pre></div><br />Once defined, we can use this function type interface like we would other interfaces. Here, we show how you can create a variable of a function type and assign it a function value of the same type.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> mySearch: SearchFunc;
mySearch = <span style="color:Blue;">function</span>(source: string, subString: string) {
<span style="color:Blue;">var</span> result = source.search(subString);
<span style="color:Blue;">if</span> (result == -1) {
<span style="color:Blue;">return</span> <span style="color:Blue;">false</span>;
}
<span style="color:Blue;">else</span> {
<span style="color:Blue;">return</span> <span style="color:Blue;">true</span>;
}
}
</pre></div><br />For function types to correctly type-check, the name of the parameters do not need to match. We could have, for example, written the above example like this:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> mySearch: SearchFunc;
mySearch = <span style="color:Blue;">function</span>(src: string, sub: string) {
<span style="color:Blue;">var</span> result = src.search(sub);
<span style="color:Blue;">if</span> (result == -1) {
<span style="color:Blue;">return</span> <span style="color:Blue;">false</span>;
}
<span style="color:Blue;">else</span> {
<span style="color:Blue;">return</span> <span style="color:Blue;">true</span>;
}
}
</pre></div><br />Function parameters are checked one at a time, with the type in each corresponding parameter position checked against each other. Here, also, the return type of our function expression is implied by the values it returns (here <i>false</i> and <i>true</i>). Had the function expression returned numbers or strings, the type-checker would have warned us that return type doesn&#39;t match the return type described in the SearchFunc interface.<br />
<h1>Array Types</h1>
Similarly to how we can use interfaces to describe function types, we can also describe array types. Array types have an &#39;index&#39; type that describes the types allowed to index the object, along with the corresponding return type for accessing the index.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> StringArray {
[index: number]: string;
}
<span style="color:Blue;">var</span> myArray: StringArray;
myArray = [<span style="color:#A31515;">&quot;Bob&quot;</span>, <span style="color:#A31515;">&quot;Fred&quot;</span>];
</pre></div> <br />There are two types of supported index types: string and number. It is possible to support both types of index, with the restriction that the type returned from the numeric index must be a subtype of the type returned from the string index.<br /><br />While index signatures are a powerful way to describe the array and &#39;dictionary&#39; pattern, they also enforce that all properties match their return type. In this example, the property does not match the more general index, and the type-checker gives an error:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Dictionary {
[index: string]: string;
length: number; <span style="color:Green;">// error, the type of &#39;length&#39; is not a subtype of the indexer</span>
}
</pre></div>
<h1>Class Types</h1>
<h2>Implementing an interface</h2>
One of the most common uses of interfaces in languages like C# and Java, that of explicitly enforcing that as class meets a particular contract, is also possible in TypeScript.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockInterface {
currentTime: Date;
}
<span style="color:Blue;">class</span> Clock <span style="color:Blue;">implements</span> ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}
</pre></div><br />You can also describe methods in an interface that are implemented in the class, as we do with &#39;setTime&#39; in the below example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockInterface {
currentTime: Date;
setTime(d: Date);
}
<span style="color:Blue;">class</span> Clock <span style="color:Blue;">implements</span> ClockInterface {
currentTime: Date;
setTime(d: Date) {
<span style="color:Blue;">this</span>.currentTime = d;
}
constructor(h: number, m: number) { }
}
</pre></div><br />Interfaces describe the public side of the class, rather than both the public and private side. This prohibits you from using them to check that a class also has particular types for the private side of the class instance.<br />
<h2>Difference between static/instance side of class</h2>
When working with classes and interfaces, it helps to keep in mind that a class has <i>two</i> types: the type of the static side and the type of the instance side. You may notice that if you create an interface with a construct signature and try to create a class that implements this interface you get an error:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockInterface {
<span style="color:Blue;">new</span> (hour: number, minute: number);
}
<span style="color:Blue;">class</span> Clock <span style="color:Blue;">implements</span> ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}
</pre></div><br />This is because when a class implements an interface, only the instance side of the class is checked. Since the constructor sits in the static side, it is not included in this check.<br /><br />Instead, you would need to work with the &#39;static&#39; side of the class directly. In this example, we work with the class directly:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockStatic {
<span style="color:Blue;">new</span> (hour: number, minute: number);
}
<span style="color:Blue;">class</span> Clock {
currentTime: Date;
constructor(h: number, m: number) { }
}
<span style="color:Blue;">var</span> cs: ClockStatic = Clock;
<span style="color:Blue;">var</span> newClock = <span style="color:Blue;">new</span> cs(7, 30);
</pre></div>
<h1>Extending Interfaces</h1>
Like classes, interfaces can extend each other. This handles the task of copying the members of one interface into another, allowing you more freedom in how you separate your interfaces into reusable components.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Shape {
color: string;
}
<span style="color:Blue;">interface</span> Square <span style="color:Blue;">extends</span> Shape {
sideLength: number;
}
<span style="color:Blue;">var</span> square = &lt;Square&gt;{};
square.color = <span style="color:#A31515;">&quot;blue&quot;</span>;
square.sideLength = 10;
</pre></div><br />An interface can extend multiple interfaces, creating a combination of all of the interfaces.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Shape {
color: string;
}
<span style="color:Blue;">interface</span> PenStroke {
penWidth: number;
}
<span style="color:Blue;">interface</span> Square <span style="color:Blue;">extends</span> Shape, PenStroke {
sideLength: number;
}
<span style="color:Blue;">var</span> square = &lt;Square&gt;{};
square.color = <span style="color:#A31515;">&quot;blue&quot;</span>;
square.sideLength = 10;
square.penWidth = 5.0;
</pre></div>
<h1>Hybrid Types</h1>
As we mentioned earlier, interfaces can describe the rich types present in real world JavaScript. Because of JavaScript&#39;s dynamic and flexible nature, you may occasionally encounter an object that works as a combination of some of the types described above. <br /><br />One such example is an object that acts as both a function and an object, with additional properties:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Counter {
(start: number): string;
interval: number;
reset(): <span style="color:Blue;">void</span>;
}
<span style="color:Blue;">var</span> c: Counter;
c(10);
c.reset();
c.interval = 5.0;
</pre></div><br />When interacting with 3rd-party JavaScript, you may need to use patterns like the above to fully-describe the shape of the type.</div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:32:30 GMTUpdated Wiki: Interfaces in TypeScript 20141103043230PUpdated Wiki: Interfaces in TypeScripthttps://typescript.codeplex.com/wikipage?title=Interfaces in TypeScript&version=15<div class="wikidoc"><i><b>Please note:</b> This page is a work-in-progress. It may have errors and is subject to change.</i><br />
<hr />
<h1>Introduction</h1>
One of TypeScript&#39;s core principles is that type-checking focuses on the &#39;shape&#39; that values have. This is sometimes called &quot;duck typing&quot; or &quot;structural subtyping&quot;. In TypeScript, interfaces fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project. <br />
<h1>Our First Interface </h1>
The easiest way to see how interfaces work is to start with a simple example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">function</span> printLabel(labelledObj: {label: string}) {
console.log(labelledObj.label);
}
<span style="color:Blue;">var</span> myObj = {size: 10, label: <span style="color:#A31515;">&quot;Size 10 Object&quot;</span>};
printLabel(myObj);
</pre></div><br />The type-checker checks the call to &#39;printLabel&#39;. The &#39;printLabel&#39; function has a single parameter that requires that the object passed in has a property called &#39;label&#39; of type string. Notice that our object actually has more properties than this, but the compiler only checks to that <i>at least</i> the ones required are present and match the types required. <br /><br />We can write the same example again, this time using an interface to describe the requirement of having the &#39;label&#39; property that is a string:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> LabelledValue {
label: string;
}
<span style="color:Blue;">function</span> printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}
<span style="color:Blue;">var</span> myObj = {size: 10, label: <span style="color:#A31515;">&quot;Size 10 Object&quot;</span>};
printLabel(myObj);
</pre></div><br />The interface &#39;LabelledValue&#39; is a name we can now use to describe the requirement in the previous example. It still represents having a single property called &#39;label&#39; that is of type string. Notice we didn&#39;t have to explicitly say that the object we pass to &#39;printLabel&#39; implements this interface like we might have to in other languages. Here, it&#39;s only the shape that matters. If the object we pass to the function meets the requirements listed, then it&#39;s allowed.<br /><br />It&#39;s worth pointing out that the type-checker does not require that these properties come in any sort of order, only that the properties the interface requires are present and have the required type.<br />
<h1>Optional Properties</h1>
Not every properties of an interface may be required. Some exist under certain conditions or may not be there at all. These optional properties are popular when creating patterns like &quot;option bags&quot; where the user passes an object to a function that only has a couple properties filled in.<br /><br />Here&#39;s as example of this pattern:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SquareConfig {
color?: string;
width?: number;
}
<span style="color:Blue;">function</span> createSquare(config: SquareConfig): {color: string; area: number} {
<span style="color:Blue;">var</span> newSquare = {color: <span style="color:#A31515;">&quot;white&quot;</span>, area: 100};
<span style="color:Blue;">if</span> (config.color) {
newSquare.color = config.color;
}
<span style="color:Blue;">if</span> (config.width) {
newSquare.area = config.width * config.width;
}
<span style="color:Blue;">return</span> newSquare;
}
<span style="color:Blue;">var</span> mySquare = createSquare({color: <span style="color:#A31515;">&quot;black&quot;</span>});
</pre></div><br />Interfaces with optional properties are written similar to other interfaces, which each optional property denoted with a &#39;?&#39; as part of the property declaration. <br /><br />The advantage of optional properties is that you can describe these possibly available properties while still also catching properties that you know are not expected to be available. For example, had we mistyped the name of the property we passed to &#39;createSquare&#39;, we would get an error message letting us know:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SquareConfig {
color?: string;
width?: number;
}
<span style="color:Blue;">function</span> createSquare(config: SquareConfig): {color: string; area: number} {
<span style="color:Blue;">var</span> newSquare = {color: <span style="color:#A31515;">&quot;white&quot;</span>, area: 100};
<span style="color:Blue;">if</span> (config.color) {
newSquare.color = config.collor; <span style="color:Green;">// Type-checker can catch the mistyped name here</span>
}
<span style="color:Blue;">if</span> (config.width) {
newSquare.area = config.width * config.width;
}
<span style="color:Blue;">return</span> newSquare;
}
<span style="color:Blue;">var</span> mySquare = createSquare({color: <span style="color:#A31515;">&quot;black&quot;</span>});
</pre></div>
<h1>Function Types</h1>
Interfaces are capable of describing the wide range of shapes that JavaScript objects can take. In addition to describing an object with properties, interfaces are also capable of describing function types.<br /><br />To describe a function type with an interface, we give the interface a call signature. This is like a function declaration with only the parameter list and return type given.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> SearchFunc {
(source: string, subString: string): <span style="color:Blue;">boolean</span>;
}
</pre></div><br />Once defined, we can use this function type interface like we would other interfaces. Here, we show how you can create a variable of a function type and assign it a function value of the same type.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> mySearch: SearchFunc;
mySearch = <span style="color:Blue;">function</span>(source: string, subString: string) {
<span style="color:Blue;">var</span> result = source.search(subString);
<span style="color:Blue;">if</span> (result == -1) {
<span style="color:Blue;">return</span> <span style="color:Blue;">false</span>;
}
<span style="color:Blue;">else</span> {
<span style="color:Blue;">return</span> <span style="color:Blue;">true</span>;
}
}
</pre></div><br />For function types to correctly type-check, the name of the parameters do not need to match. We could have, for example, written the above example like this:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">var</span> mySearch: SearchFunc;
mySearch = <span style="color:Blue;">function</span>(src: string, sub: string) {
<span style="color:Blue;">var</span> result = src.search(sub);
<span style="color:Blue;">if</span> (result == -1) {
<span style="color:Blue;">return</span> <span style="color:Blue;">false</span>;
}
<span style="color:Blue;">else</span> {
<span style="color:Blue;">return</span> <span style="color:Blue;">true</span>;
}
}
</pre></div><br />Function parameters are checked one at a time, with the type in each corresponding parameter position checked against each other. Here, also, the return type of our function expression is implied by the values it returns (here <i>false</i> and <i>true</i>). Had the function expression returned numbers or strings, the type-checker would have warned us that return type doesn&#39;t match the return type described in the SearchFunc interface.<br />
<h1>Array Types</h1>
Similarly to how we can use interfaces to describe function types, we can also describe array types. Array types have an &#39;index&#39; type that describes the types allowed to index the object, along with the corresponding return type for accessing the index.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> StringArray {
[index: number]: string;
}
<span style="color:Blue;">var</span> myArray: StringArray;
myArray = [<span style="color:#A31515;">&quot;Bob&quot;</span>, <span style="color:#A31515;">&quot;Fred&quot;</span>];
</pre></div> <br />There are two types of supported index types: string and number. It is possible to support both types of index, with the restriction that the type returned from the numeric index must be a subtype of the type returned from the string index.<br /><br />While index signatures are a powerful way to describe the array and &#39;dictionary&#39; pattern, they also enforce that all properties match their return type. In this example, the property does not match the more general index, and the type-checker gives an error:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Dictionary {
[index: string]: string;
length: number; <span style="color:Green;">// error, the type of &#39;length&#39; is not a subtype of the indexer</span>
}
</pre></div>
<h1>Class Types</h1>
<h2>Implementing an interface</h2>
One of the most common uses of interfaces in languages like C# and Java, that of explicitly enforcing that as class meets a particular contract, is also possible in TypeScript.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockInterface {
currentTime: Date;
}
<span style="color:Blue;">class</span> Clock <span style="color:Blue;">implements</span> ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}
</pre></div><br />You can also describe methods in an interface that are implemented in the class, as we do with &#39;setTime&#39; in the below example:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockInterface {
currentTime: Date;
setTime(d: Date);
}
<span style="color:Blue;">class</span> Clock <span style="color:Blue;">implements</span> ClockInterface {
currentTime: Date;
setTime(d: Date) {
<span style="color:Blue;">this</span>.currentTime = d;
}
constructor(h: number, m: number) { }
}
</pre></div><br />Interfaces describe the public side of the class, rather than both the public and private side. This prohibits you from using them to check that a class also has particular types for the private side of the class instance.<br />
<h2>Difference between static/instance side of class</h2>
When working with classes and interfaces, it helps to keep in mind that a class has <i>two</i> types: the type of the static side and the type of the instance side. You may notice that if you create an interface with a construct signature and try to create a class that implements this interface you get an error:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockInterface {
<span style="color:Blue;">new</span> (hour: number, minute: number);
}
<span style="color:Blue;">class</span> Clock <span style="color:Blue;">implements</span> ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}
</pre></div><br />This is because when a class implements an interface, only the instance side of the class is checked. Since the constructor sits in the static side, it is not included in this check.<br /><br />Instead, you would need to work with the &#39;static&#39; side of the class directly. In this example, we work with the class directly:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> ClockStatic {
<span style="color:Blue;">new</span> (hour: number, minute: number);
}
<span style="color:Blue;">class</span> Clock {
currentTime: Date;
constructor(h: number, m: number) { }
}
<span style="color:Blue;">var</span> cs: ClockStatic = Clock;
<span style="color:Blue;">var</span> newClock = <span style="color:Blue;">new</span> cs(7, 30);
</pre></div>
<h1>Extending Interfaces</h1>
Like classes, interfaces can extend each other. This handles the task of copying the members of one interface into another, allowing you more freedom in how you separate your interfaces into reusable components.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Shape {
color: string;
}
<span style="color:Blue;">interface</span> Square <span style="color:Blue;">extends</span> Shape {
sideLength: number;
}
<span style="color:Blue;">var</span> square = &lt;Square&gt;{};
square.color = <span style="color:#A31515;">&quot;blue&quot;</span>;
square.sideLength = 10;
</pre></div><br />An interface can extend multiple interfaces, creating a combination of all of the interfaces.<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Shape {
color: string;
}
<span style="color:Blue;">interface</span> PenStroke {
penWidth: number;
}
<span style="color:Blue;">interface</span> Square <span style="color:Blue;">extends</span> Shape, PenStroke {
sideLength: number;
}
<span style="color:Blue;">var</span> square = &lt;Square&gt;{};
square.color = <span style="color:#A31515;">&quot;blue&quot;</span>;
square.sideLength = 10;
square.penWidth = 5.0;
</pre></div>
<h1>Hybrid Types</h1>
As we mentioned earlier, interfaces can describe the rich types present in real world JavaScript. Because of JavaScript&#39;s dynamic and flexible nature, you may occasionally encounter an object that works as a combination of some of the types described above. <br /><br />One such example is an object that acts as both a function and an object, with additional properties:<br /><br /><div style="color:Black;background-color:White;"><pre>
<span style="color:Blue;">interface</span> Counter {
(start: number): string;
interval: number;
reset(): <span style="color:Blue;">void</span>;
}
<span style="color:Blue;">var</span> c: Counter;
c(10);
c.reset();
c.interval = 5.0;
</pre></div><br />When interacting with 3rd-party JavaScript, you may need to use patterns like the above to fully-describe the shape of the type.</div><div class="ClearBoth"></div>jonturnerMon, 03 Nov 2014 16:31:38 GMTUpdated Wiki: Interfaces in TypeScript 20141103043138PUpdated Wiki: Guidelines for Contributorshttps://typescript.codeplex.com/wikipage?title=Guidelines for Contributors&version=9<div class="wikidoc"><h1>Contributions We Accept</h1>
TypeScript is currently accepting contributions in the form of bug fixes. A bug must have an issue tracking it in the issue tracker that has been approved (Status = Active) by the TypeScript team. Your pull request should include a link to the bug that you are fixing. If you’ve submitted a PR for a bug, please post a comment in the bug to avoid duplication of effort.<br /><br />Features (things that add new or improved functionality to TypeScript) may be accepted, but will need to first be approved (marked as “Answered” by a TypeScript coordinator with the message “Approved”) in the Contribution Discussions forum. Please include [feature] in the title of your forum post. Features with language design impact, or that are adequately satisfied with external tools, will not be accepted.<br /><br />Design changes will not be accepted at this time. If you have a design change proposal, please post it to the Language Specification forum.<br />
<h1>Legal</h1>
You will need to complete a Contributor License Agreement (CLA). Briefly, this agreement testifies that you are granting us permission to use the submitted change according to the terms of the project’s license, and that the work being submitted is under appropriate copyright.<br /><br />Please submit a Contributor License Agreement (CLA) before submitting a pull request . Download the agreement (docx: <a href="https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=822190">Microsoft Contribution License Agreement.docx</a>, pdf: <a href="https://www.codeplex.com/Download?ProjectName=typescript&DownloadId=921298">Microsoft Contribution License Agreement.pdf</a>), sign, scan, and email it back to cla@microsoft. Be sure to include your <b>CodePlex user name</b> along with the agreement. Once we have received the signed CLA, we’ll review the request. Please note that we’re currently only accepting pull requests of bug fixes rather than new features.<br />
<h1>Housekeeping</h1>
Your pull request should:
<ul><li>Include a description of what your change intends to do</li>
<li>Be a child commit of a reasonably recent commit in the <b>develop</b> branch
<ul><li>Requests need not be a single commit, but should be a linear sequence of commits (i.e. no merge commits in your PR)</li></ul></li>
<li>It is desirable, but not necessary, for the tests to pass at each commit</li>
<li>Have clear commit messages
<ul><li>e.g. “Refactor <i>feature</i>”, “Fix <i>issue</i>”, “Add tests for <i>issue</i>”</li></ul></li>
<li>Include adequate tests
<ul><li>At least one test should fail in the absence of your non-test code changes. If your PR does not match this criteria, please specify why.</li>
<li>See <a href="https://typescript.codeplex.com/wikipage?title=Creating%20a%20TypeScript%20Compiler%20Test&referringTitle=Guidelines%20for%20Contributors">Creating a TypeScript Compiler Test</a> and <a href="https://typescript.codeplex.com/wikipage?title=Writing%20TypeScript%20Language%20Service%20Tests&referringTitle=Guidelines%20for%20Contributors">Writing TypeScript Language Service Tests</a> for documentation on creating tests</li>
<li>Tests should include reasonable permutations of the target fix/change</li>
<li>Include baseline changes with your change</li>
<li>All changed code must have 100% code coverage</li></ul></li>
<li>Follow the existing code conventions in the file</li></ul>
</div><div class="ClearBoth"></div>mhegazyWed, 15 Oct 2014 21:58:42 GMTUpdated Wiki: Guidelines for Contributors 20141015095842PNew Comment on "Writing Definition (.d.ts) Files"https://typescript.codeplex.com/wikipage?title=Writing Definition (.d.ts) Files&ANCHOR#C30934I&#39;m using a javascript module in node.js, and couldn&#39;t figure out how to write it&#39;s TypeScript declaration file.&#10;I created an issue on StackOverflow describing the code&#58; &#10;http&#58;&#47;&#47;stackoverflow.com&#47;questions&#47;26242880&#47;how-do-i-write-a-typescript-declaration-file-for-an-external-commonjs-module-tha&#10;&#10;In general, I find much of the documentation difficult to adapt to commonjs modules, because they are so different from internal modules. I would benefit from more documentation aimed at using TypeScript with commonjs modules for node.js.psniderTue, 07 Oct 2014 19:10:44 GMTNew Comment on "Writing Definition (.d.ts) Files" 20141007071044PNew Comment on "Modules in TypeScript"https://typescript.codeplex.com/wikipage?title=Modules in TypeScript&ANCHOR#C30921I have put together an HTML5 slide deck for my TypeScript-on-Node.js presentation for a local Meetup,&#10;and would greatly appreciate someone reviewing it.&#10;&#10;Keep in mind that it&#39;s just the bullet points, and a guide for my presentation.&#10;&#10;If you&#39;re interested, you can review my slide deck on my personal site&#58; &#10;http&#58;&#47;&#47;morning-savannah-8290.herokuapp.com&#47;Typescript-on-Nodejs&#47;index.html &#10;The presentation is a static HTML5 page, with a PPT slide-like presentation, except that it&#39;s 2D &#40;a row of columns&#41; . Navigate via the arrow keys on screen or on your keyboard. The top slide on each column is a summary. Any details are in slides in the same column. &#10;&#10;My contact info is at the bottom of the first page.&#10;&#10;Thanks in advance...psniderFri, 03 Oct 2014 00:59:09 GMTNew Comment on "Modules in TypeScript" 20141003125909ANew Comment on "Modules in TypeScript"https://typescript.codeplex.com/wikipage?title=Modules in TypeScript&ANCHOR#C30920I have put together an HTML5 slide deck for my presentation,&#10;and would greatly appreciate someone reviewing it.&#10;&#10;Keep in mind that it&#39;s just the bullet points, and a guide for my presentation.&#10;&#10;If you&#39;re interested, you can review my slide deck on my personal site&#58; &#10;http&#58;&#47;&#47;morning-savannah-8290.herokuapp.com&#47;Typescript-on-Nodejs&#47;index.html &#10;The presentation is a static HTML5 page, with a PPT slide-like presentation, except that it&#39;s 2D &#40;a row of columns&#41; . Navigate via the arrow keys on screen or on your keyboard. The top slide on each column is a summary. Any details are in slides in the same column. &#10;&#10;My contact info is at the bottom of the first page.&#10;&#10;Thanks in advance...psniderFri, 03 Oct 2014 00:57:34 GMTNew Comment on "Modules in TypeScript" 20141003125734ANew Comment on "Classes in TypeScript"https://typescript.codeplex.com/wikipage?title=Classes in TypeScript&ANCHOR#C30876Good question MikNik. Typescript uses angle brackets for casts, e.g. &#10;&#96;&#96;&#96;&#10;this.document &#61; &#60;Document&#62;d&#59;&#10;&#96;&#96;&#96;BurtHarrisWed, 24 Sep 2014 17:29:50 GMTNew Comment on "Classes in TypeScript" 20140924052950P