TypeScript 2.0

Null- and undefined-aware types TypeScript has two special types, Null and Undefined, that have the values null and undefined respectively. Previously it was not possible to explicitly name these types, but null and undefined may now be used as type names regardless of type checking mode. The type checker previously considered null and undefined assignable to anything. Effectively, null and undefined were valid values of every type and it wasn’t possible to specifically exclude them (and theref

Enum

Enum A helpful addition to the standard set of datatypes from JavaScript is the enum. As in languages like C#, an enum is a way of giving more friendly names to sets of numeric values. enum Color {Red, Green, Blue}; let c: Color = Color.Green; By default, enums begin numbering their members starting at 0. You can change this by manually setting the value of one of its members. For example, we can start the previous example at 1 instead of 0: enum Color {Red = 1, Green, Blue}; let c: Color = Co

Definition File Theory: A Deep Dive

Definition File Theory: A Deep Dive Structuring modules to give the exact API shape you want can be tricky. For example, we might want a module that can be invoked with or without new to produce different types, has a variety of named types exposed in a hierarchy, and has some properties on the module object as well. By reading this guide, you’ll have the tools to write complex definition files that expose a friendly API surface. This guide focuses on module (or UMD) libraries because the optio

compileOnSave

compileOnSave Setting a top-level property compileOnSave signals to the IDE to generate all files for a given tsconfig.json upon saving. { "compileOnSave": true, "compilerOptions": { "noImplicitAny" : true } } This feature is currently supported in Visual Studio 2015 with TypeScript 1.8.4 and above, and atom-typescript plugin.

Typing the function

Typing the function Let’s add types to our simple examples from earlier: function add(x: number, y: number): number { return x + y; } let myAdd = function(x: number, y: number): number { return x+y; }; We can add types to each of the parameters and then to the function itself to add a return type. TypeScript can figure the return type out by looking at the return statements, so we can also optionally leave this off in many cases.

Export statements

Export statements Export statements are handy when exports need to be renamed for consumers, so the above example can be written as: class ZipCodeValidator implements StringValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } } export { ZipCodeValidator }; export { ZipCodeValidator as mainValidator };

Splitting Across Files

Splitting Across Files As our application grows, we’ll want to split the code across multiple files to make it easier to maintain.

Use Optional Parameters

Use Optional Parameters Don’t write several overloads that differ only in trailing parameters: /* WRONG */ interface Moment { diff(b: MomentComparable): number; diff(b: MomentComparable, unitOfTime: string): number; diff(b: MomentComparable, unitOfTime: string, round: boolean): number; } Do use optional parameters whenever possible: /* OK */ interface Moment { diff(b: MomentComparable, unitOfTime?: string, round?: boolean): number; } Note that this collapsing should only occur when al

Attribute type checking

Attribute type checking The first step to type checking attributes is to determine the element attributes type. This is slightly different between intrinsic and value-based elements. For intrinsic elements, it is the type of the property on JSX.IntrinsicElements declare namespace JSX { interface IntrinsicElements { foo: { bar?: boolean } } } // element attributes type for 'foo' is '{bar?: boolean}' <foo bar />; For value-based elements, it is a bit more complex. It is determined b

Hybrid Types

Hybrid Types As we mentioned earlier, interfaces can describe the rich types present in real world JavaScript. Because of JavaScript’s dynamic and flexible nature, you may occasionally encounter an object that works as a combination of some of the types described above. One such example is an object that acts as both a function and an object, with additional properties: interface Counter { (start: number): string; interval: number; reset(): void; } function getCounter(): Counter { let