├── .gitignore ├── .travis.yml ├── .gitattributes ├── pages ├── Typings for NPM Packages.md ├── Writing Declaration Files.md ├── declaration files │ ├── Templates.md │ ├── templates │ │ ├── global-plugin.d.ts.md │ │ ├── global-modifying-module.d.ts.md │ │ ├── module-plugin.d.ts.md │ │ ├── module.d.ts.md │ │ ├── module-class.d.ts.md │ │ ├── global.d.ts.md │ │ └── module-function.d.ts.md │ ├── Consumption.md │ ├── Introduction.md │ ├── Publishing.md │ ├── By Example.md │ ├── Do's and Don'ts.md │ └── Deep Dive.md ├── tutorials │ ├── Angular.md │ ├── TypeScript in 5 minutes.md │ └── React & Webpack.md ├── release notes │ ├── TypeScript 1.1.md │ ├── TypeScript 1.3.md │ ├── TypeScript 2.5.md │ ├── TypeScript 2.4.md │ ├── TypeScript 1.7.md │ ├── TypeScript 1.4.md │ ├── TypeScript 2.2.md │ └── TypeScript 2.3.md ├── Iterators and Generators.md ├── Nightly Builds.md ├── Symbols.md ├── Type Inference.md ├── Mixins.md ├── Triple-Slash Directives.md ├── Namespaces and Modules.md ├── Integrating with Build Tools.md ├── Type Checking JavaScript Files.md ├── tsconfig.json.md ├── Compiler Options in MSBuild.md ├── Enums.md ├── Basic Types.md ├── Namespaces.md └── Type Compatibility.md ├── assets └── images │ └── tutorials │ └── aspnet │ ├── new-folder.png │ ├── new-item.png │ ├── open-index.png │ ├── src-folder.png │ ├── new-tsconfig.png │ ├── paused-demo.png │ ├── running-demo.png │ ├── new-asp-project.png │ ├── scripts-folder.png │ ├── task-runner-explorer.png │ ├── install-nuget-packages.png │ ├── new-asp-project-empty.png │ ├── new-asp-project-empty-17.PNG │ ├── packageinstaller-angular2.png │ ├── packageinstaller-es6-shim.png │ ├── packageinstaller-systemjs.png │ └── packageinstaller-typings.png ├── CONTRIBUTING.md ├── README.md ├── package.json ├── pull_request_template.md └── lint.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Normalize line endings for all text files. 2 | * text=auto 3 | -------------------------------------------------------------------------------- /pages/Typings for NPM Packages.md: -------------------------------------------------------------------------------- 1 | > ## This page has been moved to [Publishing](./declaration files/Publishing.md) 2 | -------------------------------------------------------------------------------- /pages/Writing Declaration Files.md: -------------------------------------------------------------------------------- 1 | > ## This page has been moved to [Publishing](./declaration files/Introduction.md) 2 | -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/new-folder.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/new-item.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/open-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/open-index.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/src-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/src-folder.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-tsconfig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/new-tsconfig.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/paused-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/paused-demo.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/running-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/running-demo.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-asp-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/new-asp-project.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/scripts-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/scripts-folder.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/task-runner-explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/task-runner-explorer.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/install-nuget-packages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/install-nuget-packages.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-asp-project-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/new-asp-project-empty.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/new-asp-project-empty-17.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/new-asp-project-empty-17.PNG -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/packageinstaller-angular2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/packageinstaller-angular2.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/packageinstaller-es6-shim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/packageinstaller-es6-shim.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/packageinstaller-systemjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/packageinstaller-systemjs.png -------------------------------------------------------------------------------- /assets/images/tutorials/aspnet/packageinstaller-typings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ry/TypeScript-Handbook/HEAD/assets/images/tutorials/aspnet/packageinstaller-typings.png -------------------------------------------------------------------------------- /pages/declaration files/Templates.md: -------------------------------------------------------------------------------- 1 | * [global-modifying-module.d.ts](./templates/global-modifying-module.d.ts.md) 2 | * [global-plugin.d.ts](./templates/global-plugin.d.ts.md) 3 | * [global.d.ts](./templates/global.d.ts.md) 4 | * [module-class.d.ts](./templates/module-class.d.ts.md) 5 | * [module-function.d.ts](./templates/module-function.d.ts.md) 6 | * [module-plugin.d.ts](./templates/module-plugin.d.ts.md) 7 | * [module.d.ts](./templates/module.d.ts.md) -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | TypeScript-Handbook is accepting contributions. If you've submitted a PR for an existing issue, please post a comment in the issue to avoid duplication of effort. 4 | 5 | ## Housekeeping 6 | 7 | Your pull request should: 8 | 9 | * Include a description of what your change intends to do. 10 | * Have a clear commit messages 11 | * e.g. "New Topic", "Fix typo", "Add code samples" 12 | * For code samples, please make sure they compile against the latest released TypeScript compiler version. 13 | -------------------------------------------------------------------------------- /pages/tutorials/Angular.md: -------------------------------------------------------------------------------- 1 | Angular is a modern framework built entirely in TypeScript, and as a result, using TypeScript with Angular provides a seamless experience. 2 | 3 | The Angular documentation not only supports TypeScript as a first-class citizen, but uses it as its primary language. 4 | With this in mind, [Angular's site](https://angular.io) will always be the most up-to-date reference for using Angular with TypeScript. 5 | 6 | Check out the [quick start guide here](https://angular.io/docs/ts/latest/quickstart.html) to start learning Angular now! -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TypeScript-Handbook 2 | 3 | [![Build Status](https://travis-ci.org/Microsoft/TypeScript-Handbook.svg)](https://travis-ci.org/Microsoft/TypeScript-Handbook) 4 | 5 | The TypeScript Handbook is a comprehensive guide to the TypeScript language. 6 | It is meant to be read online at [the TypeScript website](https://www.typescriptlang.org/docs/handbook/basic-types.html) or [directly from this repository](./pages/Basic%20Types.md). 7 | 8 | For a more formal description of the language, see the [latest TypeScript Language Specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md). 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript-handbook", 3 | "version": "1.0.0", 4 | "description": "The TypeScript Handbook is a comprehensive guide to the TypeScript language", 5 | "main": "none", 6 | "scripts": { 7 | "test": "node lint.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Microsoft/TypeScript-Handbook.git" 12 | }, 13 | "author": "", 14 | "license": "Apache-2.0", 15 | "bugs": { 16 | "url": "https://github.com/Microsoft/TypeScript-Handbook/issues" 17 | }, 18 | "homepage": "https://github.com/Microsoft/TypeScript-Handbook#readme", 19 | "devDependencies": { 20 | "glob": "^5.0.15", 21 | "markdownlint": "latest" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | 16 | 17 | Fixes # 18 | -------------------------------------------------------------------------------- /pages/release notes/TypeScript 1.1.md: -------------------------------------------------------------------------------- 1 | # Performance Improvements 2 | 3 | The 1.1 compiler is typically around 4x faster than any previous release. See [this blog post for some impressive charts.](http://blogs.msdn.com/b/typescript/archive/2014/10/06/announcing-typescript-1-1-ctp.aspx) 4 | 5 | # Better Module Visibility Rules 6 | 7 | TypeScript now only strictly enforces the visibility of types in modules if the `--declaration` flag is provided. This is very useful for Angular scenarios, for example: 8 | 9 | ```ts 10 | module MyControllers { 11 | interface ZooScope extends ng.IScope { 12 | animals: Animal[]; 13 | } 14 | export class ZooController { 15 | // Used to be an error (cannot expose ZooScope), but now is only 16 | // an error when trying to generate .d.ts files 17 | constructor(public $scope: ZooScope) { } 18 | /* more code */ 19 | } 20 | } 21 | ``` -------------------------------------------------------------------------------- /pages/declaration files/templates/global-plugin.d.ts.md: -------------------------------------------------------------------------------- 1 | ```ts 2 | // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~] 3 | // Project: [~THE PROJECT NAME~] 4 | // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]> 5 | 6 | /*~ This template shows how to write a global plugin. */ 7 | 8 | /*~ Write a declaration for the original type and add new members. 9 | *~ For example, this adds a 'toBinaryString' method with to overloads to 10 | *~ the built-in number type. 11 | */ 12 | interface Number { 13 | toBinaryString(opts?: MyLibrary.BinaryFormatOptions): string; 14 | toBinaryString(callback: MyLibrary.BinaryFormatCallback, opts?: MyLibrary.BinaryFormatOptions): string; 15 | } 16 | 17 | /*~ If you need to declare several types, place them inside a namespace 18 | *~ to avoid adding too many things to the global namespace. 19 | */ 20 | declare namespace MyLibrary { 21 | type BinaryFormatCallback = (n: number) => string; 22 | interface BinaryFormatOptions { 23 | prefix?: string; 24 | padding: number; 25 | } 26 | } 27 | ``` -------------------------------------------------------------------------------- /pages/declaration files/templates/global-modifying-module.d.ts.md: -------------------------------------------------------------------------------- 1 | ```ts 2 | // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~] 3 | // Project: [~THE PROJECT NAME~] 4 | // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]> 5 | 6 | /*~ This is the global-modifying module template file. You should rename it to index.d.ts 7 | *~ and place it in a folder with the same name as the module. 8 | *~ For example, if you were writing a file for "super-greeter", this 9 | *~ file should be 'super-greeter/index.d.ts' 10 | */ 11 | 12 | /*~ Note: If your global-modifying module is callable or constructable, you'll 13 | *~ need to combine the patterns here with those in the module-class or module-function 14 | *~ template files 15 | */ 16 | declare global { 17 | /*~ Here, declare things that go in the global namespace, or augment 18 | *~ existing declarations in the global namespace 19 | */ 20 | interface String { 21 | fancyFormat(opts: StringFormatOptions): string; 22 | } 23 | } 24 | 25 | /*~ If your module exports types or values, write them as usual */ 26 | export interface StringFormatOptions { 27 | fancinessLevel: number; 28 | } 29 | 30 | /*~ For example, declaring a method on the module (in addition to its global side effects) */ 31 | export function doSomething(): void; 32 | 33 | /*~ If your module exports nothing, you'll need this line. Otherwise, delete it */ 34 | export { }; 35 | ``` -------------------------------------------------------------------------------- /pages/declaration files/templates/module-plugin.d.ts.md: -------------------------------------------------------------------------------- 1 | ```ts 2 | // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~] 3 | // Project: [~THE PROJECT NAME~] 4 | // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]> 5 | 6 | /*~ This is the module plugin template file. You should rename it to index.d.ts 7 | *~ and place it in a folder with the same name as the module. 8 | *~ For example, if you were writing a file for "super-greeter", this 9 | *~ file should be 'super-greeter/index.d.ts' 10 | */ 11 | 12 | /*~ On this line, import the module which this module adds to */ 13 | import * as m from 'someModule'; 14 | 15 | /*~ You can also import other modules if needed */ 16 | import * as other from 'anotherModule'; 17 | 18 | /*~ Here, declare the same module as the one you imported above */ 19 | declare module 'someModule' { 20 | /*~ Inside, add new function, classes, or variables. You can use 21 | *~ unexported types from the original module if needed. */ 22 | export function theNewMethod(x: m.foo): other.bar; 23 | 24 | /*~ You can also add new properties to existing interfaces from 25 | *~ the original module by writing interface augmentations */ 26 | export interface SomeModuleOptions { 27 | someModuleSetting?: string; 28 | } 29 | 30 | /*~ New types can also be declared and will appear as if they 31 | *~ are in the original module */ 32 | export interface MyModulePluginOptions { 33 | size: number; 34 | } 35 | } 36 | ``` -------------------------------------------------------------------------------- /pages/release notes/TypeScript 1.3.md: -------------------------------------------------------------------------------- 1 | # Protected 2 | 3 | The new `protected` modifier in classes works like it does in familiar languages like C++, C#, and Java. A `protected` member of a class is visible only inside subclasses of the class in which it is declared: 4 | 5 | ```ts 6 | class Thing { 7 | protected doSomething() { /* ... */ } 8 | } 9 | 10 | class MyThing extends Thing { 11 | public myMethod() { 12 | // OK, can access protected member from subclass 13 | this.doSomething(); 14 | } 15 | } 16 | var t = new MyThing(); 17 | t.doSomething(); // Error, cannot call protected member from outside class 18 | ``` 19 | 20 | # Tuple types 21 | 22 | Tuple types express an array where the type of certain elements is known, but need not be the same. For example, you may want to represent an array with a `string` at position 0 and a `number` at position 1: 23 | 24 | ```ts 25 | // Declare a tuple type 26 | var x: [string, number]; 27 | // Initialize it 28 | x = ['hello', 10]; // OK 29 | // Initialize it incorrectly 30 | x = [10, 'hello']; // Error 31 | ``` 32 | 33 | When accessing an element with a known index, the correct type is retrieved: 34 | 35 | ```ts 36 | console.log(x[0].substr(1)); // OK 37 | console.log(x[1].substr(1)); // Error, 'number' does not have 'substr' 38 | ``` 39 | 40 | Note that in TypeScript 1.4, when accessing an element outside the set of known indices, a union type is used instead: 41 | 42 | ```ts 43 | x[3] = 'world'; // OK 44 | console.log(x[5].toString()); // OK, 'string' and 'number' both have toString 45 | x[6] = true; // Error, boolean isn't number or string 46 | ``` -------------------------------------------------------------------------------- /pages/declaration files/templates/module.d.ts.md: -------------------------------------------------------------------------------- 1 | ```ts 2 | // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~] 3 | // Project: [~THE PROJECT NAME~] 4 | // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]> 5 | 6 | /*~ This is the module template file. You should rename it to index.d.ts 7 | *~ and place it in a folder with the same name as the module. 8 | *~ For example, if you were writing a file for "super-greeter", this 9 | *~ file should be 'super-greeter/index.d.ts' 10 | */ 11 | 12 | /*~ If this module is a UMD module that exposes a global variable 'myLib' when 13 | *~ loaded outside a module loader environment, declare that global here. 14 | *~ Otherwise, delete this declaration. 15 | */ 16 | export as namespace myLib; 17 | 18 | /*~ If this module has methods, declare them as functions like so. 19 | */ 20 | export function myMethod(a: string): string; 21 | export function myOtherMethod(a: number): number; 22 | 23 | /*~ You can declare types that are available via importing the module */ 24 | export interface someType { 25 | name: string; 26 | length: number; 27 | extras?: string[]; 28 | } 29 | 30 | /*~ You can declare properties of the module using const, let, or var */ 31 | export const myField: number; 32 | 33 | /*~ If there are types, properties, or methods inside dotted names 34 | *~ of the module, declare them inside a 'namespace'. 35 | */ 36 | export namespace subProp { 37 | /*~ For example, given this definition, someone could write: 38 | *~ import { subProp } from 'yourModule'; 39 | *~ subProp.foo(); 40 | *~ or 41 | *~ import * as yourMod from 'yourModule'; 42 | *~ yourMod.subProp.foo(); 43 | */ 44 | export function foo(): void; 45 | } 46 | ``` -------------------------------------------------------------------------------- /pages/declaration files/templates/module-class.d.ts.md: -------------------------------------------------------------------------------- 1 | ```ts 2 | // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~] 3 | // Project: [~THE PROJECT NAME~] 4 | // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]> 5 | 6 | /*~ This is the module template file for class modules. 7 | *~ You should rename it to index.d.ts and place it in a folder with the same name as the module. 8 | *~ For example, if you were writing a file for "super-greeter", this 9 | *~ file should be 'super-greeter/index.d.ts' 10 | */ 11 | 12 | /*~ Note that ES6 modules cannot directly export class objects. 13 | *~ This file should be imported using the CommonJS-style: 14 | *~ import x = require('someLibrary'); 15 | *~ 16 | *~ Refer to the documentation to understand common 17 | *~ workarounds for this limitation of ES6 modules. 18 | */ 19 | 20 | /*~ If this module is a UMD module that exposes a global variable 'myClassLib' when 21 | *~ loaded outside a module loader environment, declare that global here. 22 | *~ Otherwise, delete this declaration. 23 | */ 24 | export as namespace myClassLib; 25 | 26 | /*~ This declaration specifies that the class constructor function 27 | *~ is the exported object from the file 28 | */ 29 | export = MyClass; 30 | 31 | /*~ Write your module's methods and properties in this class */ 32 | declare class MyClass { 33 | constructor(someParam?: string); 34 | 35 | someProperty: string[]; 36 | 37 | myMethod(opts: MyClass.MyClassMethodOptions): number; 38 | } 39 | 40 | /*~ If you want to expose types from your module as well, you can 41 | *~ place them in this block. 42 | */ 43 | declare namespace MyClass { 44 | export interface MyClassMethodOptions { 45 | width?: number; 46 | height?: number; 47 | } 48 | } 49 | ``` -------------------------------------------------------------------------------- /pages/declaration files/Consumption.md: -------------------------------------------------------------------------------- 1 | In TypeScript 2.0, it has become significantly easier to consume declaration files, in acquiring, using, and finding them. 2 | This page details exactly how to do all three. 3 | 4 | # Downloading 5 | 6 | Getting type declarations in TypeScript 2.0 and above requires no tools apart from npm. 7 | 8 | As an example, getting the declarations for a library like lodash takes nothing more than the following command 9 | 10 | ```cmd 11 | npm install --save @types/lodash 12 | ``` 13 | 14 | It is worth noting that if the npm package already includes its declaration file as described in [Publishing](./Publishing.md), downloading the corresponding `@types` package is not needed. 15 | 16 | # Consuming 17 | 18 | From there you’ll be able to use lodash in your TypeScript code with no fuss. 19 | This works for both modules and global code. 20 | 21 | For example, once you’ve `npm install`-ed your type declarations, you can use imports and write 22 | 23 | ```ts 24 | import * as _ from "lodash"; 25 | _.padStart("Hello TypeScript!", 20, " "); 26 | ``` 27 | 28 | or if you’re not using modules, you can just use the global variable `_`. 29 | 30 | ```ts 31 | _.padStart("Hello TypeScript!", 20, " "); 32 | ``` 33 | 34 | # Searching 35 | 36 | For the most part, type declaration packages should always have the same name as the package name on `npm`, but prefixed with `@types/`, 37 | but if you need, you can check out [https://aka.ms/types](https://aka.ms/types) to find the package for your favorite library. 38 | 39 | > Note: if the declaration file you are searching for is not present, you can always contribute one back and help out the next developer looking for it. 40 | > Please see the DefinitelyTyped [contribution guidelines page](http://definitelytyped.org/guides/contributing.html) for details. 41 | -------------------------------------------------------------------------------- /pages/declaration files/templates/global.d.ts.md: -------------------------------------------------------------------------------- 1 | ```ts 2 | // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~] 3 | // Project: [~THE PROJECT NAME~] 4 | // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]> 5 | 6 | /*~ If this library is callable (e.g. can be invoked as myLib(3)), 7 | *~ include those call signatures here. 8 | *~ Otherwise, delete this section. 9 | */ 10 | declare function myLib(a: string): string; 11 | declare function myLib(a: number): number; 12 | 13 | /*~ If you want the name of this library to be a valid type name, 14 | *~ you can do so here. 15 | *~ 16 | *~ For example, this allows us to write 'var x: myLib'; 17 | *~ Be sure this actually makes sense! If it doesn't, just 18 | *~ delete this declaration and add types inside the namespace below. 19 | */ 20 | interface myLib { 21 | name: string; 22 | length: number; 23 | extras?: string[]; 24 | } 25 | 26 | /*~ If your library has properties exposed on a global variable, 27 | *~ place them here. 28 | *~ You should also place types (interfaces and type alias) here. 29 | */ 30 | declare namespace myLib { 31 | //~ We can write 'myLib.timeout = 50;' 32 | let timeout: number; 33 | 34 | //~ We can access 'myLib.version', but not change it 35 | const version: string; 36 | 37 | //~ There's some class we can create via 'let c = new myLib.Cat(42)' 38 | //~ Or reference e.g. 'function f(c: myLib.Cat) { ... } 39 | class Cat { 40 | constructor(n: number); 41 | 42 | //~ We can read 'c.age' from a 'Cat' instance 43 | readonly age: number; 44 | 45 | //~ We can invoke 'c.purr()' from a 'Cat' instance 46 | purr(): void; 47 | } 48 | 49 | //~ We can declare a variable as 50 | //~ 'var s: myLib.CatSettings = { weight: 5, name: "Maru" };' 51 | interface CatSettings { 52 | weight: number; 53 | name: string; 54 | tailLength?: number; 55 | } 56 | 57 | //~ We can write 'const v: myLib.VetID = 42;' 58 | //~ or 'const v: myLib.VetID = "bob";' 59 | type VetID = string | number; 60 | 61 | //~ We can invoke 'myLib.checkCat(c)' or 'myLib.checkCat(c, v);' 62 | function checkCat(c: Cat, s?: VetID); 63 | } 64 | ``` -------------------------------------------------------------------------------- /pages/declaration files/templates/module-function.d.ts.md: -------------------------------------------------------------------------------- 1 | ```ts 2 | // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~] 3 | // Project: [~THE PROJECT NAME~] 4 | // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]> 5 | 6 | /*~ This is the module template file for function modules. 7 | *~ You should rename it to index.d.ts and place it in a folder with the same name as the module. 8 | *~ For example, if you were writing a file for "super-greeter", this 9 | *~ file should be 'super-greeter/index.d.ts' 10 | */ 11 | 12 | /*~ Note that ES6 modules cannot directly export callable functions. 13 | *~ This file should be imported using the CommonJS-style: 14 | *~ import x = require('someLibrary'); 15 | *~ 16 | *~ Refer to the documentation to understand common 17 | *~ workarounds for this limitation of ES6 modules. 18 | */ 19 | 20 | /*~ If this module is a UMD module that exposes a global variable 'myFuncLib' when 21 | *~ loaded outside a module loader environment, declare that global here. 22 | *~ Otherwise, delete this declaration. 23 | */ 24 | export as namespace myFuncLib; 25 | 26 | /*~ This declaration specifies that the function 27 | *~ is the exported object from the file 28 | */ 29 | export = MyFunction; 30 | 31 | /*~ This example shows how to have multiple overloads for your function */ 32 | declare function MyFunction(name: string): MyFunction.NamedReturnType; 33 | declare function MyFunction(length: number): MyFunction.LengthReturnType; 34 | 35 | /*~ If you want to expose types from your module as well, you can 36 | *~ place them in this block. Often you will want to describe the 37 | *~ shape of the return type of the function; that type should 38 | *~ be declared in here, as this example shows. 39 | */ 40 | declare namespace MyFunction { 41 | export interface LengthReturnType { 42 | width: number; 43 | height: number; 44 | } 45 | export interface NamedReturnType { 46 | firstName: string; 47 | lastName: string; 48 | } 49 | 50 | /*~ If the module also has properties, declare them here. For example, 51 | *~ this declaration says that this code is legal: 52 | *~ import f = require('myFuncLibrary'); 53 | *~ console.log(f.defaultName); 54 | */ 55 | export const defaultName: string; 56 | export let defaultLength: number; 57 | } 58 | ``` -------------------------------------------------------------------------------- /pages/declaration files/Introduction.md: -------------------------------------------------------------------------------- 1 | This guide is designed to teach you how to write a high-quality TypeScript Declaration File. 2 | 3 | In this guide, we'll assume basic familiarity with the TypeScript language. 4 | If you haven't already, you should read the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html) 5 | to familiarize yourself with basic concepts, especially types and namespaces. 6 | 7 | # Sections 8 | 9 | The guide is broken down into the following sections. 10 | 11 | ## Library Structures 12 | 13 | The [Library Structures](./Library Structures.md) guide helps you understand common library formats and how to write a correct declaration file for each format. 14 | If you're editing an existing file, you probably don't need to read this section. 15 | Authors of new declaration files must read this section to properly understand how the format of the library influences the writing of the declaration file. 16 | 17 | ## "Do"s and "Don't"s 18 | 19 | Many common mistakes in declaration files can be easily avoided. 20 | The [Do's and Don'ts](./Do's and Don'ts.md) section identifies common errors, 21 | describes how to detect them, 22 | and how to fix them. 23 | Everyone should read this section to help themselves avoid common mistakes. 24 | 25 | ## By Example 26 | 27 | Many times, we are faced with writing a declaration file when we only have examples of the underlying library to guide us. 28 | The [By Example](./By Example.md) section shows many common API patterns and how to write declarations for each of them. 29 | This guide is aimed at the TypeScript novice who may not yet be familiar with every language construct in TypeScript. 30 | 31 | ## Deep Dive 32 | 33 | For seasoned authors interested in the underlying mechanics of how declaration files work, 34 | the [Deep Dive](./Deep Dive.md) section explains many advanced concepts in declaration writing, 35 | and shows how to leverage these concepts to create cleaner and more intuitive declaration files. 36 | 37 | ## Templates 38 | 39 | In [Templates](./Templates.md) you'll find a number of declaration files that serve as a useful starting point 40 | when writing a new file. 41 | Refer to the documentation in [Library Structures](./Library Structures.md) to figure out which template file to use. 42 | 43 | ## Publish to npm 44 | 45 | The [Publishing](./Publishing.md) section explains how to publish your declaration files to an npm package, and shows how to manage your dependent packages. 46 | 47 | ## Find and Install Declaration Files 48 | 49 | For JavaScript library users, the [Consumption](./Consumption.md) section offers a few simple steps to locate and install corresponding declaration files. 50 | -------------------------------------------------------------------------------- /pages/release notes/TypeScript 2.5.md: -------------------------------------------------------------------------------- 1 | # Optional `catch` clause variables 2 | 3 | Thanks to work done by [@tinganho](https://github.com/tinganho), TypeScript 2.5 implements a new ECMAScript feature that allows users to omit the variable in `catch` clauses. 4 | For example, when using `JSON.parse` you may need to wrap calls to the function with a `try`/`catch`, but you may not end up using the `SyntaxError` that gets thrown when input is erroneous. 5 | 6 | ```ts 7 | let input = "..."; 8 | try { 9 | JSON.parse(input); 10 | } 11 | catch { 12 | // ^ Notice that our `catch` clause doesn't declare a variable. 13 | console.log("Invalid JSON given\n\n" + input) 14 | } 15 | ``` 16 | 17 | # Type assertion/cast syntax in `checkJs`/`@ts-check` mode 18 | 19 | TypeScript 2.5 introduces the ability to [assert the type of expressions when using plain JavaScript in your projects](https://github.com/Microsoft/TypeScript/issues/5158). 20 | The syntax is an `/** @type {...} */` annotation comment followed by a parenthesized expression whose type needs to be re-evaluated. 21 | For example: 22 | 23 | ```ts 24 | var x = /** @type {SomeType} */ (AnyParenthesizedExpression); 25 | ``` 26 | 27 | # Deduplicated and redirected packages 28 | 29 | When importing using the `Node` module resolution strategy in TypeScript 2.5, the compiler will now check whether files originate from "identical" packages. 30 | If a file originates from a package with a `package.json` containing the same `name` and `version` fields as a previously encountered package, then TypeScript will redirect itself to the top-most package. 31 | This helps resolve problems where two packages might contain identical declarations of classes, but which contain `private` members that cause them to be structurally incompatible. 32 | 33 | As a nice bonus, this can also reduce the memory and runtime footprint of the compiler and language service by avoiding loading `.d.ts` files from duplicate packages. 34 | 35 | # The `--preserveSymlinks` compiler flag 36 | 37 | TypeScript 2.5 brings the `preserveSymlinks` flag, which parallels the behavior of [the `--preserve-symlinks` flag in Node.js](https://nodejs.org/api/cli.html#cli_preserve_symlinks). 38 | This flag also exhibits the opposite behavior to Webpack's `resolve.symlinks` option (i.e. setting TypeScript's `preserveSymlinks` to `true` parallels setting Webpack's `resolve.symlinks` to `false`, and vice-versa). 39 | 40 | In this mode, references to modules and packages (e.g. `import`s and `/// ` directives) are all resolved relative to the location of the symbolic link file, rather than relative to the path that the symbolic link resolves to. 41 | For a more concrete example, we'll defer to [the documentation on the Node.js website](https://nodejs.org/api/cli.html#cli_preserve_symlinks). 42 | -------------------------------------------------------------------------------- /pages/Iterators and Generators.md: -------------------------------------------------------------------------------- 1 | # Iterables 2 | 3 | An object is deemed iterable if it has an implementation for the [`Symbol.iterator`](Symbols.md#symboliterator) property. 4 | Some built-in types like `Array`, `Map`, `Set`, `String`, `Int32Array`, `Uint32Array`, etc. have their `Symbol.iterator` property already implemented. 5 | `Symbol.iterator` function on an object is responsible for returning the list of values to iterate on. 6 | 7 | ## `for..of` statements 8 | 9 | `for..of` loops over an iterable object, invoking the `Symbol.iterator` property on the object. 10 | Here is a simple `for..of` loop on an array: 11 | 12 | ```ts 13 | let someArray = [1, "string", false]; 14 | 15 | for (let entry of someArray) { 16 | console.log(entry); // 1, "string", false 17 | } 18 | ``` 19 | 20 | ### `for..of` vs. `for..in` statements 21 | 22 | Both `for..of` and `for..in` statements iterate over lists; the values iterated on are different though, `for..in` returns a list of *keys* on the object being iterated, whereas `for..of` returns a list of *values* of the numeric properties of the object being iterated. 23 | 24 | Here is an example that demonstrates this distinction: 25 | 26 | ```ts 27 | let list = [4, 5, 6]; 28 | 29 | for (let i in list) { 30 | console.log(i); // "0", "1", "2", 31 | } 32 | 33 | for (let i of list) { 34 | console.log(i); // "4", "5", "6" 35 | } 36 | ``` 37 | 38 | Another distinction is that `for..in` operates on any object; it serves as a way to inspect properties on this object. 39 | `for..of` on the other hand, is mainly interested in values of iterable objects. Built-in objects like `Map` and `Set` implement `Symbol.iterator` property allowing access to stored values. 40 | 41 | ```ts 42 | let pets = new Set(["Cat", "Dog", "Hamster"]); 43 | pets["species"] = "mammals"; 44 | 45 | for (let pet in pets) { 46 | console.log(pet); // "species" 47 | } 48 | 49 | for (let pet of pets) { 50 | console.log(pet); // "Cat", "Dog", "Hamster" 51 | } 52 | ``` 53 | 54 | ### Code generation 55 | 56 | #### Targeting ES5 and ES3 57 | 58 | When targeting an ES5 or ES3, iterators are only allowed on values of `Array` type. 59 | It is an error to use `for..of` loops on non-Array values, even if these non-Array values implement the `Symbol.iterator` property. 60 | 61 | The compiler will generate a simple `for` loop for a `for..of` loop, for instance: 62 | 63 | ```ts 64 | let numbers = [1, 2, 3]; 65 | for (let num of numbers) { 66 | console.log(num); 67 | } 68 | ``` 69 | 70 | will be generated as: 71 | 72 | ```js 73 | var numbers = [1, 2, 3]; 74 | for (var _i = 0; _i < numbers.length; _i++) { 75 | var num = numbers[_i]; 76 | console.log(num); 77 | } 78 | ``` 79 | 80 | #### Targeting ECMAScript 2015 and higher 81 | 82 | When targeting an ECMAScipt 2015-compliant engine, the compiler will generate `for..of` loops to target the built-in iterator implementation in the engine. 83 | -------------------------------------------------------------------------------- /pages/Nightly Builds.md: -------------------------------------------------------------------------------- 1 | A nightly build from the [TypeScript's `master`](https://github.com/Microsoft/TypeScript/tree/master) branch is published by midnight PST to NPM and NuGet. 2 | Here is how you can get it and use it with your tools. 3 | 4 | ## Using npm 5 | 6 | ```shell 7 | npm install -g typescript@next 8 | ``` 9 | 10 | ## Using NuGet with MSBuild 11 | 12 | > Note: You'll need to configure your project to use the NuGet packages. 13 | Please see [Configuring MSBuild projects to use NuGet](https://github.com/Microsoft/TypeScript/wiki/Configuring-MSBuild-projects-to-use-NuGet) for more information. 14 | 15 | The nightlies are available on [www.myget.org](https://www.myget.org/gallery/typescript-preview). 16 | 17 | There are two packages: 18 | 19 | * `Microsoft.TypeScript.Compiler`: Tools only (`tsc.exe`, `lib.d.ts`, etc.) . 20 | * `Microsoft.TypeScript.MSBuild`: Tools as above, as well as MSBuild tasks and targets (`Microsoft.TypeScript.targets`, `Microsoft.TypeScript.Default.props`, etc.) 21 | 22 | ## Updating your IDE to use the nightly builds 23 | 24 | You can also update your IDE to use the nightly drop. 25 | First you will need to install the package through npm. 26 | You can either install the npm package globally or to a local `node_modules` folder. 27 | 28 | The rest of this section assumes `typescript@next` is already installed. 29 | 30 | ### Visual Studio Code 31 | 32 | Update `.vscode/settings.json` with the following: 33 | 34 | ```json 35 | "typescript.tsdk": "/node_modules/typescript/lib" 36 | ``` 37 | 38 | More information is available at [VSCode documentation](https://code.visualstudio.com/Docs/languages/typescript#_using-newer-typescript-versions). 39 | 40 | ### Sublime Text 41 | 42 | Update the `Settings - User` file with the following: 43 | 44 | ```json 45 | "typescript_tsdk": "/node_modules/typescript/lib" 46 | ``` 47 | 48 | More information is available at the [TypeScript Plugin for Sublime Text installation documentation](https://github.com/Microsoft/TypeScript-Sublime-Plugin#installation). 49 | 50 | ### Visual Studio 2013 and 2015 51 | 52 | > Note: Most changes do not require you to install a new version of the VS TypeScript plugin. 53 | 54 | The nightly build currently does not include the full plugin setup, but we are working on publishing an installer on a nightly basis as well. 55 | 56 | 1. Download the [VSDevMode.ps1](https://github.com/Microsoft/TypeScript/blob/master/scripts/VSDevMode.ps1) script. 57 | 58 | > Also see our wiki page on [using a custom language service file](https://github.com/Microsoft/TypeScript/wiki/Dev-Mode-in-Visual-Studio#using-a-custom-language-service-file). 59 | 60 | 2. From a PowerShell command window, run: 61 | 62 | For VS 2015: 63 | 64 | ```posh 65 | VSDevMode.ps1 14 -tsScript /node_modules/typescript/lib 66 | ``` 67 | 68 | For VS 2013: 69 | 70 | ```posh 71 | VSDevMode.ps1 12 -tsScript /node_modules/typescript/lib 72 | ``` 73 | 74 | ### IntelliJ IDEA (Mac) 75 | 76 | Go to `Preferences` > `Languages & Frameworks` > `TypeScript`: 77 | > TypeScript Version: If you installed with npm: `/usr/local/lib/node_modules/typescript/lib` 78 | -------------------------------------------------------------------------------- /pages/Symbols.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Starting with ECMAScript 2015, `symbol` is a primitive data type, just like `number` and `string`. 4 | 5 | `symbol` values are created by calling the `Symbol` constructor. 6 | 7 | ```ts 8 | let sym1 = Symbol(); 9 | 10 | let sym2 = Symbol("key"); // optional string key 11 | ``` 12 | 13 | Symbols are immutable, and unique. 14 | 15 | ```ts 16 | let sym2 = Symbol("key"); 17 | let sym3 = Symbol("key"); 18 | 19 | sym2 === sym3; // false, symbols are unique 20 | ``` 21 | 22 | Just like strings, symbols can be used as keys for object properties. 23 | 24 | ```ts 25 | let sym = Symbol(); 26 | 27 | let obj = { 28 | [sym]: "value" 29 | }; 30 | 31 | console.log(obj[sym]); // "value" 32 | ``` 33 | 34 | Symbols can also be combined with computed property declarations to declare object properties and class members. 35 | 36 | ```ts 37 | const getClassNameSymbol = Symbol(); 38 | 39 | class C { 40 | [getClassNameSymbol](){ 41 | return "C"; 42 | } 43 | } 44 | 45 | let c = new C(); 46 | let className = c[getClassNameSymbol](); // "C" 47 | ``` 48 | 49 | # Well-known Symbols 50 | 51 | In addition to user-defined symbols, there are well-known built-in symbols. 52 | Built-in symbols are used to represent internal language behaviors. 53 | 54 | Here is a list of well-known symbols: 55 | 56 | ## `Symbol.hasInstance` 57 | 58 | A method that determines if a constructor object recognizes an object as one of the constructor’s instances. Called by the semantics of the instanceof operator. 59 | 60 | ## `Symbol.isConcatSpreadable` 61 | 62 | A Boolean value indicating that an object should be flatten to its array elements by Array.prototype.concat. 63 | 64 | ## `Symbol.iterator` 65 | 66 | A method that returns the default iterator for an object. Called by the semantics of the for-of statement. 67 | 68 | ## `Symbol.match` 69 | 70 | A regular expression method that matches the regular expression against a string. Called by the `String.prototype.match` method. 71 | 72 | ## `Symbol.replace` 73 | 74 | A regular expression method that replaces matched substrings of a string. Called by the `String.prototype.replace` method. 75 | 76 | ## `Symbol.search` 77 | 78 | A regular expression method that returns the index within a string that matches the regular expression. Called by the `String.prototype.search` method. 79 | 80 | ## `Symbol.species` 81 | 82 | A function valued property that is the constructor function that is used to create derived objects. 83 | 84 | ## `Symbol.split` 85 | 86 | A regular expression method that splits a string at the indices that match the regular expression. 87 | Called by the `String.prototype.split` method. 88 | 89 | ## `Symbol.toPrimitive` 90 | 91 | A method that converts an object to a corresponding primitive value. 92 | Called by the `ToPrimitive` abstract operation. 93 | 94 | ## `Symbol.toStringTag` 95 | 96 | A String value that is used in the creation of the default string description of an object. 97 | Called by the built-in method `Object.prototype.toString`. 98 | 99 | ## `Symbol.unscopables` 100 | 101 | An Object whose own property names are property names that are excluded from the 'with' environment bindings of the associated objects. 102 | -------------------------------------------------------------------------------- /pages/Type Inference.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In this section, we will cover type inference in TypeScript. Namely, we'll discuss where and how types are inferred. 4 | 5 | # Basics 6 | 7 | In TypeScript, there are several places where type inference is used to provide type information when there is no explicit type annotation. For example, in this code 8 | 9 | ```ts 10 | let x = 3; 11 | ``` 12 | 13 | The type of the `x` variable is inferred to be `number`. 14 | This kind of inference takes place when initializing variables and members, setting parameter default values, and determining function return types. 15 | 16 | In most cases, type inference is straightforward. 17 | In the following sections, we'll explore some of the nuances in how types are inferred. 18 | 19 | # Best common type 20 | 21 | When a type inference is made from several expressions, the types of those expressions are used to calculate a "best common type". For example, 22 | 23 | ```ts 24 | let x = [0, 1, null]; 25 | ``` 26 | 27 | To infer the type of `x` in the example above, we must consider the type of each array element. 28 | Here we are given two choices for the type of the array: `number` and `null`. 29 | The best common type algorithm considers each candidate type, and picks the type that is compatible with all the other candidates. 30 | 31 | Because the best common type has to be chosen from the provided candidate types, there are some cases where types share a common structure, but no one type is the super type of all candidate types. For example: 32 | 33 | ```ts 34 | let zoo = [new Rhino(), new Elephant(), new Snake()]; 35 | ``` 36 | 37 | Ideally, we may want `zoo` to be inferred as an `Animal[]`, but because there is no object that is strictly of type `Animal` in the array, we make no inference about the array element type. 38 | To correct this, instead explicitly provide the type when no one type is a super type of all other candidates: 39 | 40 | ```ts 41 | let zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()]; 42 | ``` 43 | 44 | When no best common type is found, the resulting inference is the union array type, `(Rhino | Elephant | Snake)[]`. 45 | 46 | # Contextual Type 47 | 48 | Type inference also works in "the other direction" in some cases in TypeScript. 49 | This is known as "contextual typing". Contextual typing occurs when the type of an expression is implied by its location. For example: 50 | 51 | ```ts 52 | window.onmousedown = function(mouseEvent) { 53 | console.log(mouseEvent.button); //<- Error 54 | }; 55 | ``` 56 | 57 | For the code above to give the type error, the TypeScript type checker used the type of the `Window.onmousedown` function to infer the type of the function expression on the right hand side of the assignment. 58 | When it did so, it was able to infer the type of the `mouseEvent` parameter. 59 | If this function expression were not in a contextually typed position, the `mouseEvent` parameter would have type `any`, and no error would have been issued. 60 | 61 | If the contextually typed expression contains explicit type information, the contextual type is ignored. 62 | Had we written the above example: 63 | 64 | ```ts 65 | window.onmousedown = function(mouseEvent: any) { 66 | console.log(mouseEvent.button); //<- Now, no error is given 67 | }; 68 | ``` 69 | 70 | The function expression with an explicit type annotation on the parameter will override the contextual type. 71 | Once it does so, no error is given as no contextual type applies. 72 | 73 | Contextual typing applies in many cases. 74 | Common cases include arguments to function calls, right hand sides of assignments, type assertions, members of object and array literals, and return statements. 75 | The contextual type also acts as a candidate type in best common type. For example: 76 | 77 | ```ts 78 | function createZoo(): Animal[] { 79 | return [new Rhino(), new Elephant(), new Snake()]; 80 | } 81 | ``` 82 | 83 | In this example, best common type has a set of four candidates: `Animal`, `Rhino`, `Elephant`, and `Snake`. 84 | Of these, `Animal` can be chosen by the best common type algorithm. 85 | -------------------------------------------------------------------------------- /pages/declaration files/Publishing.md: -------------------------------------------------------------------------------- 1 | Now that you have authored a declaration file following the steps of this guide, it is time to publish it to npm. 2 | There are two main ways you can publish your declaration files to npm: 3 | 4 | 1. bundling with your npm package, or 5 | 2. publishing to the [@types organization](https://www.npmjs.com/~types) on npm. 6 | 7 | If you control the npm package you are publishing declarations for, then the first approach is favored. 8 | That way, your declarations and JavaScript always travel together. 9 | 10 | # Including declarations in your npm package 11 | 12 | If your package has a main `.js` file, you will need to indicate the main declaration file in your `package.json` file as well. 13 | Set the `types` property to point to your bundled declaration file. 14 | For example: 15 | 16 | ```json 17 | { 18 | "name": "awesome", 19 | "author": "Vandelay Industries", 20 | "version": "1.0.0", 21 | "main": "./lib/main.js", 22 | "types": "./lib/main.d.ts" 23 | } 24 | ``` 25 | 26 | Note that the `"typings"` field is synonymous with `"types"`, and could be used as well. 27 | 28 | Also note that if your main declaration file is named `index.d.ts` and lives at the root of the package (next to `index.js`) you do not need to mark the `"types"` property, though it is advisable to do so. 29 | 30 | ## Dependencies 31 | 32 | All dependencies are managed by npm. 33 | Make sure all the declaration packages you depend on are marked appropriately in the `"dependencies"` section in your `package.json`. 34 | For example, imagine we authored a package that used Browserify and TypeScript. 35 | 36 | ```json 37 | { 38 | "name": "browserify-typescript-extension", 39 | "author": "Vandelay Industries", 40 | "version": "1.0.0", 41 | "main": "./lib/main.js", 42 | "types": "./lib/main.d.ts", 43 | "dependencies": { 44 | "browserify": "latest", 45 | "@types/browserify": "latest", 46 | "typescript": "next" 47 | } 48 | } 49 | ``` 50 | 51 | Here, our package depends on the `browserify` and `typescript` packages. 52 | `browserify` does not bundle its declaration files with its npm packages, so we needed to depend on `@types/browserify` for its declarations. 53 | `typescript`, on the other hand, packages its declaration files, so there was no need for any additional dependencies 54 | 55 | Our package exposes declarations from each of those, so any user of our `browserify-typescript-extension` package needs to have these dependencies as well. 56 | For that reason, we used `"dependencies"` and not `"devDependencies"`, because otherwise our consumers would have needed to manually install those packages. 57 | If we had just written a command line application and not expected our package to be used as a library, we might have used `devDependencies`. 58 | 59 | ## Red flags 60 | 61 | ### `/// ` 62 | 63 | *Don't* use `/// ` in your declaration files. 64 | 65 | ```ts 66 | /// 67 | .... 68 | ``` 69 | 70 | *Do* use `/// ` instead. 71 | 72 | ```ts 73 | /// 74 | .... 75 | ``` 76 | 77 | Make sure to revisit the [Consuming dependencies](./Library Structures.md#consuming-dependencies) section for more information. 78 | 79 | ### Packaging dependent declarations 80 | 81 | If your type definitions depend on another package: 82 | 83 | * *Don't* combine it with yours, keep each in their own file. 84 | * *Don't* copy the declarations in your package either. 85 | * *Do* depend on the npm type declaration package if it doesn't package its declaration files. 86 | 87 | # Publish to [@types](https://www.npmjs.com/~types) 88 | 89 | Packages on under the [@types](https://www.npmjs.com/~types) organization are published automatically from [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) using the [types-publisher tool](https://github.com/Microsoft/types-publisher). 90 | To get your declarations published as an @types package, please submit a pull request to [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped). 91 | You can find more details in the [contribution guidelines page](http://definitelytyped.org/guides/contributing.html). 92 | -------------------------------------------------------------------------------- /pages/Mixins.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Along with traditional OO hierarchies, another popular way of building up classes from reusable components is to build them by combining simpler partial classes. 4 | You may be familiar with the idea of mixins or traits for languages like Scala, and the pattern has also reached some popularity in the JavaScript community. 5 | 6 | # Mixin sample 7 | 8 | In the code below, we show how you can model mixins in TypeScript. 9 | After the code, we'll break down how it works. 10 | 11 | ```ts 12 | // Disposable Mixin 13 | class Disposable { 14 | isDisposed: boolean; 15 | dispose() { 16 | this.isDisposed = true; 17 | } 18 | 19 | } 20 | 21 | // Activatable Mixin 22 | class Activatable { 23 | isActive: boolean; 24 | activate() { 25 | this.isActive = true; 26 | } 27 | deactivate() { 28 | this.isActive = false; 29 | } 30 | } 31 | 32 | class SmartObject implements Disposable, Activatable { 33 | constructor() { 34 | setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500); 35 | } 36 | 37 | interact() { 38 | this.activate(); 39 | } 40 | 41 | // Disposable 42 | isDisposed: boolean = false; 43 | dispose: () => void; 44 | // Activatable 45 | isActive: boolean = false; 46 | activate: () => void; 47 | deactivate: () => void; 48 | } 49 | applyMixins(SmartObject, [Disposable, Activatable]); 50 | 51 | let smartObj = new SmartObject(); 52 | setTimeout(() => smartObj.interact(), 1000); 53 | 54 | //////////////////////////////////////// 55 | // In your runtime library somewhere 56 | //////////////////////////////////////// 57 | 58 | function applyMixins(derivedCtor: any, baseCtors: any[]) { 59 | baseCtors.forEach(baseCtor => { 60 | Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { 61 | derivedCtor.prototype[name] = baseCtor.prototype[name]; 62 | }); 63 | }); 64 | } 65 | ``` 66 | 67 | # Understanding the sample 68 | 69 | The code sample starts with the two classes that will act as our mixins. 70 | You can see each one is focused on a particular activity or capability. 71 | We'll later mix these together to form a new class from both capabilities. 72 | 73 | ```ts 74 | // Disposable Mixin 75 | class Disposable { 76 | isDisposed: boolean; 77 | dispose() { 78 | this.isDisposed = true; 79 | } 80 | 81 | } 82 | 83 | // Activatable Mixin 84 | class Activatable { 85 | isActive: boolean; 86 | activate() { 87 | this.isActive = true; 88 | } 89 | deactivate() { 90 | this.isActive = false; 91 | } 92 | } 93 | ``` 94 | 95 | Next, we'll create the class that will handle the combination of the two mixins. 96 | Let's look at this in more detail to see how it does this: 97 | 98 | ```ts 99 | class SmartObject implements Disposable, Activatable { 100 | ``` 101 | 102 | The first thing you may notice in the above is that instead of using `extends`, we use `implements`. 103 | This treats the classes as interfaces, and only uses the types behind Disposable and Activatable rather than the implementation. 104 | This means that we'll have to provide the implementation in class. 105 | Except, that's exactly what we want to avoid by using mixins. 106 | 107 | To satisfy this requirement, we create stand-in properties and their types for the members that will come from our mixins. 108 | This satisfies the compiler that these members will be available at runtime. 109 | This lets us still get the benefit of the mixins, albeit with some bookkeeping overhead. 110 | 111 | ```ts 112 | // Disposable 113 | isDisposed: boolean = false; 114 | dispose: () => void; 115 | // Activatable 116 | isActive: boolean = false; 117 | activate: () => void; 118 | deactivate: () => void; 119 | ``` 120 | 121 | Finally, we mix our mixins into the class, creating the full implementation. 122 | 123 | ```ts 124 | applyMixins(SmartObject, [Disposable, Activatable]); 125 | ``` 126 | 127 | Lastly, we create a helper function that will do the mixing for us. 128 | This will run through the properties of each of the mixins and copy them over to the target of the mixins, filling out the stand-in properties with their implementations. 129 | 130 | ```ts 131 | function applyMixins(derivedCtor: any, baseCtors: any[]) { 132 | baseCtors.forEach(baseCtor => { 133 | Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { 134 | derivedCtor.prototype[name] = baseCtor.prototype[name]; 135 | }); 136 | }); 137 | } 138 | 139 | ``` 140 | -------------------------------------------------------------------------------- /lint.js: -------------------------------------------------------------------------------- 1 | var markdownlint = require("markdownlint"); 2 | var glob = require("glob"); 3 | var fs = require("fs"); 4 | 5 | var inputFiles = glob.sync("**/*.md", { ignore: "node_modules/**/*" }); 6 | var options = { 7 | files: inputFiles, 8 | config: { 9 | MD001: false, // Header levels should only increment by one level at a time 10 | MD002: false, // First header should be a h1 header 11 | MD003: "atx", // Header style 12 | MD004: { style: "asterisk" }, // Unordered list style 13 | MD005: true, // Inconsistent indentation for list items at the same level 14 | MD006: true, // Consider starting bulleted lists at the beginning of the line 15 | MD007: { indent: 4 }, // Unordered list indentation 16 | MD009: true, // Trailing spaces 17 | MD010: true, // Hard tabs 18 | MD011: true, // Reversed link syntax 19 | MD012: true, // Multiple consecutive blank lines 20 | MD013: false, // Line length 21 | MD014: false, // Dollar signs used before commands without showing output 22 | MD018: true, // No space after hash on atx style header 23 | MD019: true, // Multiple spaces after hash on atx style header 24 | MD020: false, // No space inside hashes on closed atx style header 25 | MD021: false, // Multiple spaces inside hashes on closed atx style header 26 | MD022: true, // Headers should be surrounded by blank lines 27 | MD023: true, // Headers must start at the beginning of the line 28 | MD024: false, // Multiple headers with the same content 29 | MD025: false, // Multiple top level headers in the same document 30 | MD026: { punctuation: ".,;:!" }, // Trailing punctuation in header 31 | MD027: true, // Multiple spaces after blockquote symbol 32 | MD028: true, // Blank line inside blockquote 33 | MD029: { style: "ordered" }, // Ordered list item prefix 34 | MD030: true, // Spaces after list markers 35 | MD031: true, // Fenced code blocks should be surrounded by blank lines 36 | MD032: true, // Lists should be surrounded by blank lines 37 | MD033: false, // Inline HTML 38 | MD034: true, // Bare URL used 39 | MD035: "---", // Horizontal rule style 40 | MD036: false, // Emphasis used instead of a header 41 | MD037: true, // Spaces inside emphasis markers 42 | MD038: false, // Spaces inside code span elements 43 | MD039: true, // Spaces inside link text 44 | MD040: true, // Fenced code blocks should have a language specified 45 | MD041: false, // First line in file should be a top level header 46 | } 47 | }; 48 | 49 | var result = markdownlint.sync(options); 50 | console.log(result.toString()); 51 | 52 | var exitCode = 0; 53 | Object.keys(result).forEach(function (file) { 54 | var fileResults = result[file]; 55 | Object.keys(fileResults).forEach(function (rule) { 56 | var ruleResults = fileResults[rule]; 57 | exitCode += ruleResults.length; 58 | }); 59 | }); 60 | 61 | inputFiles.forEach(function(fileName) { 62 | var text = fs.readFileSync(fileName, "utf8") 63 | exitCode += checkForImproperlyIndentedFencedCodeBlocks(fileName, text); 64 | }) 65 | 66 | process.exit(exitCode); 67 | 68 | /** 69 | * @param {string} fileName 70 | * @param {string} text 71 | */ 72 | function checkForImproperlyIndentedFencedCodeBlocks(fileName, text) { 73 | var lines = text.split(/\r?\n/g); 74 | var numErrors = 0; 75 | 76 | for (var i = 0; i < lines.length; i++) { 77 | var line = lines[i]; 78 | var codeBlockMatch = line.match(/^(\s*)```\S+/); 79 | 80 | if (codeBlockMatch) { 81 | var startingColumn = codeBlockMatch[1].length; 82 | if (startingColumn === 0 || startingColumn === getCorrectStartingColumnForLine(lines, i)) { 83 | continue; 84 | } 85 | 86 | numErrors++; 87 | console.log(fileName + ": " + 88 | i + 1 + ": A fenced code block following a list item must be indented to the first non-whitespace character of the list item.") 89 | } 90 | } 91 | 92 | return numErrors; 93 | } 94 | 95 | /** 96 | * @param {string[]} line 97 | * @param {number} lineIndex 98 | */ 99 | function getCorrectStartingColumnForLine(lines, lineIndex) { 100 | for (var i = lineIndex - 1; i >= 0; i--) { 101 | var line = lines[i]; 102 | 103 | if (line.length === 0) { 104 | continue; 105 | } 106 | 107 | var m; 108 | if (m = line.match(/^\s*([\*\-]|(\d+\.))\s*/)) { 109 | return m[0].length; 110 | } 111 | if (m = line.match(/^(\s*)/)) { 112 | return m[0].length; 113 | } 114 | } 115 | 116 | return 0; 117 | } -------------------------------------------------------------------------------- /pages/Triple-Slash Directives.md: -------------------------------------------------------------------------------- 1 | Triple-slash directives are single-line comments containing a single XML tag. 2 | The contents of the comment are used as compiler directives. 3 | 4 | Triple-slash directives are **only** valid at the top of their containing file. 5 | A triple-slash directive can only be preceded by single or multi-line comments, including other triple-slash directives. 6 | If they are encountered following a statement or a declaration they are treated as regular single-line comments, and hold no special meaning. 7 | 8 | ## `/// ` 9 | 10 | The `/// ` directive is the most common of this group. 11 | It serves as a declaration of *dependency* between files. 12 | 13 | Triple-slash references instruct the compiler to include additional files in the compilation process. 14 | 15 | They also serve as a method to order the output when using `--out` or `--outFile`. 16 | Files are emitted to the output file location in the same order as the input after preprocessing pass. 17 | 18 | ### Preprocessing input files 19 | 20 | The compiler performs a preprocessing pass on input files to resolve all triple-slash reference directives. 21 | During this process, additional files are added to the compilation. 22 | 23 | The process starts with a set of *root files*; 24 | these are the file names specified on the command-line or in the `"files"` list in the `tsconfig.json` file. 25 | These root files are preprocessed in the same order they are specified. 26 | Before a file is added to the list, all triple-slash references in it are processed, and their targets included. 27 | Triple-slash references are resolved in a depth first manner, in the order they have been seen in the file. 28 | 29 | A triple-slash reference path is resolved relative to the containing file, if unrooted. 30 | 31 | ### Errors 32 | 33 | It is an error to reference a file that does not exist. 34 | It is an error for a file to have a triple-slash reference to itself. 35 | 36 | ### Using `--noResolve` 37 | 38 | If the compiler flag `--noResolve` is specified, triple-slash references are ignored; they neither result in adding new files, nor change the order of the files provided. 39 | 40 | ## `/// ` 41 | 42 | Similar to a `/// ` directive, this directive serves as a declaration of *dependency*; 43 | a `/// ` directive, however, declares a dependency on a package. 44 | 45 | The process of resolving these package names is similar to the process of resolving module names in an `import` statement. 46 | An easy way to think of triple-slash-reference-types directives are as an `import` for declaration packages. 47 | 48 | For example, including `/// ` in a declaration file declares that this file uses names declared in `@types/node/index.d.ts`; 49 | and thus, this package needs to be included in the compilation along with the declaration file. 50 | 51 | Use these directives only when you're authoring a `d.ts` file by hand. 52 | 53 | For declaration files generated during compilation, the compiler will automatically add `/// ` for you; 54 | A `/// ` in a generated declaration file is added *if and only if* the resulting file uses any declarations from the referenced package. 55 | 56 | For declaring a dependency on an `@types` package in a `.ts` file, use `--types` on the command line or in your `tsconfig.json` instead. 57 | See [using `@types`, `typeRoots` and `types` in `tsconfig.json` files](./tsconfig.json.md#types-typeroots-and-types) for more details. 58 | 59 | ## `/// ` 60 | 61 | This directive marks a file as a *default library*. 62 | You will see this comment at the top of `lib.d.ts` and its different variants. 63 | 64 | This directive instructs the compiler to *not* include the default library (i.e. `lib.d.ts`) in the compilation. 65 | The impact here is similar to passing `--noLib` on the command line. 66 | 67 | Also note that when passing `--skipDefaultLibCheck`, the compiler will only skip checking files with `/// `. 68 | 69 | ## `/// ` 70 | 71 | By default AMD modules are generated anonymous. 72 | This can lead to problems when other tools are used to process the resulting modules, such as bundlers (e.g. `r.js`). 73 | 74 | The `amd-module` directive allows passing an optional module name to the compiler: 75 | 76 | ##### amdModule.ts 77 | 78 | ```ts 79 | /// 80 | export class C { 81 | } 82 | ``` 83 | 84 | Will result in assigning the name `NamedModule` to the module as part of calling the AMD `define`: 85 | 86 | ##### amdModule.js 87 | 88 | ```js 89 | define("NamedModule", ["require", "exports"], function (require, exports) { 90 | var C = (function () { 91 | function C() { 92 | } 93 | return C; 94 | })(); 95 | exports.C = C; 96 | }); 97 | ``` 98 | 99 | ## `/// ` 100 | 101 | > **Note**: this directive has been deprecated. Use `import "moduleName";` statements instead. 102 | 103 | `/// ` informs the compiler about a non-TS module dependency that needs to be injected in the resulting module's require call. 104 | 105 | The `amd-dependency` directive can also have an optional `name` property; this allows passing an optional name for an amd-dependency: 106 | 107 | ```ts 108 | /// 109 | declare var moduleA:MyType 110 | moduleA.callStuff() 111 | ``` 112 | 113 | Generated JS code: 114 | 115 | ```js 116 | define(["require", "exports", "legacy/moduleA"], function (require, exports, moduleA) { 117 | moduleA.callStuff() 118 | }); 119 | ``` 120 | -------------------------------------------------------------------------------- /pages/Namespaces and Modules.md: -------------------------------------------------------------------------------- 1 | > **A note about terminology:** 2 | It's important to note that in TypeScript 1.5, the nomenclature has changed. 3 | "Internal modules" are now "namespaces". 4 | "External modules" are now simply "modules", as to align with [ECMAScript 2015](http://www.ecma-international.org/ecma-262/6.0/)'s terminology, (namely that `module X {` is equivalent to the now-preferred `namespace X {`). 5 | 6 | # Introduction 7 | 8 | This post outlines the various ways to organize your code using namespaces and modules in TypeScript. 9 | We'll also go over some advanced topics of how to use namespaces and modules, and address some common pitfalls when using them in TypeScript. 10 | 11 | See the [Modules](./Modules.md) documentation for more information about modules. 12 | See the [Namespaces](./Namespaces.md) documentation for more information about namespaces. 13 | 14 | # Using Namespaces 15 | 16 | Namespaces are simply named JavaScript objects in the global namespace. 17 | This makes namespaces a very simple construct to use. 18 | They can span multiple files, and can be concatenated using `--outFile`. 19 | Namespaces can be a good way to structure your code in a Web Application, with all dependencies included as ` 155 | 156 | 157 | ``` 158 | 159 | Open `greeter.html` in the browser to run your first simple TypeScript web application! 160 | 161 | Optional: Open `greeter.ts` in Visual Studio, or copy the code into the TypeScript playground. 162 | You can hover over identifiers to see their types. 163 | Notice that in some cases these types are inferred automatically for you. 164 | Re-type the last line, and see completion lists and parameter help based on the types of the DOM elements. 165 | Put your cursor on the reference to the greeter function, and hit F12 to go to its definition. 166 | Notice, too, that you can right-click on a symbol and use refactoring to rename it. 167 | 168 | The type information provided works together with the tools to work with JavaScript at application scale. 169 | For more examples of what's possible in TypeScript, see the Samples section of the website. 170 | 171 | ![Visual Studio picture](/assets/images/docs/greet_person.png) 172 | -------------------------------------------------------------------------------- /pages/declaration files/By Example.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The purpose of this guide is to teach you how to write a high-quality definition file. 4 | This guide is structured by showing documentation for some API, along with sample usage of that API, 5 | and explaining how to write the corresponding declaration. 6 | 7 | These examples are ordered in approximately increasing order of complexity. 8 | 9 | * [Global Variables](#global-variables) 10 | * [Global Functions](#global-functions) 11 | * [Objects with Properties](#objects-with-properties) 12 | * [Overloaded Function](#overloaded-functions) 13 | * [Reusable Types (Interfaces)](#reusable-types-interfaces) 14 | * [Reusable Types (Type Aliases)](#reusable-types-type-aliases) 15 | * [Organizing Types](#organizing-types) 16 | * [Classes](#classes) 17 | 18 | # The Examples 19 | 20 | ## Global Variables 21 | 22 | *Documentation* 23 | 24 | > The global variable `foo` contains the number of widgets present. 25 | 26 | *Code* 27 | 28 | ```ts 29 | console.log("Half the number of widgets is " + (foo / 2)); 30 | ``` 31 | 32 | *Declaration* 33 | 34 | Use `declare var` to declare variables. 35 | If the variable is read-only, you can use `declare const`. 36 | You can also use `declare let` if the variable is block-scoped. 37 | 38 | ```ts 39 | /** The number of widgets present */ 40 | declare var foo: number; 41 | ``` 42 | 43 | ## Global Functions 44 | 45 | *Documentation* 46 | 47 | > You can call the function `greet` with a string to show a greeting to the user. 48 | 49 | *Code* 50 | 51 | ```ts 52 | greet("hello, world"); 53 | ``` 54 | 55 | *Declaration* 56 | 57 | Use `declare function` to declare functions. 58 | 59 | ```ts 60 | declare function greet(greeting: string): void; 61 | ``` 62 | 63 | ## Objects with Properties 64 | 65 | *Documentation* 66 | 67 | > The global variable `myLib` has a function `makeGreeting` for creating greetings, 68 | > and a property `numberOfGreetings` indicating the number of greetings made so far. 69 | 70 | *Code* 71 | 72 | ```ts 73 | let result = myLib.makeGreeting("hello, world"); 74 | console.log("The computed greeting is:" + result); 75 | 76 | let count = myLib.numberOfGreetings; 77 | ``` 78 | 79 | *Declaration* 80 | 81 | Use `declare namespace` to describe types or values accessed by dotted notation. 82 | 83 | ```ts 84 | declare namespace myLib { 85 | function makeGreeting(s: string): string; 86 | let numberOfGreetings: number; 87 | } 88 | ``` 89 | 90 | ## Overloaded Functions 91 | 92 | *Documentation* 93 | 94 | The `getWidget` function accepts a number and returns a Widget, or accepts a string and returns a Widget array. 95 | 96 | *Code* 97 | 98 | ```ts 99 | let x: Widget = getWidget(43); 100 | 101 | let arr: Widget[] = getWidget("all of them"); 102 | ``` 103 | 104 | *Declaration* 105 | 106 | ```ts 107 | declare function getWidget(n: number): Widget; 108 | declare function getWidget(s: string): Widget[]; 109 | ``` 110 | 111 | ## Reusable Types (Interfaces) 112 | 113 | *Documentation* 114 | 115 | > When specifying a greeting, you must pass a `GreetingSettings` object. 116 | > This object has the following properties: 117 | > 118 | > 1 - greeting: Mandatory string 119 | > 120 | > 2 - duration: Optional length of time (in milliseconds) 121 | > 122 | > 3 - color: Optional string, e.g. '#ff00ff' 123 | 124 | *Code* 125 | 126 | ```ts 127 | greet({ 128 | greeting: "hello world", 129 | duration: 4000 130 | }); 131 | ``` 132 | 133 | *Declaration* 134 | 135 | Use an `interface` to define a type with properties. 136 | 137 | ```ts 138 | interface GreetingSettings { 139 | greeting: string; 140 | duration?: number; 141 | color?: string; 142 | } 143 | 144 | declare function greet(setting: GreetingSettings): void; 145 | ``` 146 | 147 | ## Reusable Types (Type Aliases) 148 | 149 | *Documentation* 150 | 151 | > Anywhere a greeting is expected, you can provide a `string`, a function returning a `string`, or a `Greeter` instance. 152 | 153 | *Code* 154 | 155 | ```ts 156 | function getGreeting() { 157 | return "howdy"; 158 | } 159 | class MyGreeter extends Greeter { } 160 | 161 | greet("hello"); 162 | greet(getGreeting); 163 | greet(new MyGreeter()); 164 | ``` 165 | 166 | *Declaration* 167 | 168 | You can use a type alias to make a shorthand for a type: 169 | 170 | ```ts 171 | type GreetingLike = string | (() => string) | MyGreeter; 172 | 173 | declare function greet(g: GreetingLike): void; 174 | ``` 175 | 176 | ## Organizing Types 177 | 178 | *Documentation* 179 | 180 | > The `greeter` object can log to a file or display an alert. 181 | > You can provide LogOptions to `.log(...)` and alert options to `.alert(...)` 182 | 183 | *Code* 184 | 185 | ```ts 186 | const g = new Greeter("Hello"); 187 | g.log({ verbose: true }); 188 | g.alert({ modal: false, title: "Current Greeting" }); 189 | ``` 190 | 191 | *Declaration* 192 | 193 | Use namespaces to organize types. 194 | 195 | ```ts 196 | declare namespace GreetingLib { 197 | interface LogOptions { 198 | verbose?: boolean; 199 | } 200 | interface AlertOptions { 201 | modal: boolean; 202 | title?: string; 203 | color?: string; 204 | } 205 | } 206 | ``` 207 | 208 | You can also create nested namespaces in one declaration: 209 | 210 | ```ts 211 | declare namespace GreetingLib.Options { 212 | // Refer to via GreetingLib.Options.Log 213 | interface Log { 214 | verbose?: boolean; 215 | } 216 | interface Alert { 217 | modal: boolean; 218 | title?: string; 219 | color?: string; 220 | } 221 | } 222 | ``` 223 | 224 | ## Classes 225 | 226 | *Documentation* 227 | 228 | > You can create a greeter by instantiating the `Greeter` object, or create a customized greeter by extending from it. 229 | 230 | *Code* 231 | 232 | ```ts 233 | const myGreeter = new Greeter("hello, world"); 234 | myGreeter.greeting = "howdy"; 235 | myGreeter.showGreeting(); 236 | 237 | class SpecialGreeter extends Greeter { 238 | constructor() { 239 | super("Very special greetings"); 240 | } 241 | } 242 | ``` 243 | 244 | *Declaration* 245 | 246 | Use `declare class` to describe a class or class-like object. 247 | Classes can have properties and methods as well as a constructor. 248 | 249 | ```ts 250 | declare class Greeter { 251 | constructor(greeting: string); 252 | 253 | greeting: string; 254 | showGreeting(): void; 255 | } 256 | ``` 257 | 258 | 278 | -------------------------------------------------------------------------------- /pages/Type Checking JavaScript Files.md: -------------------------------------------------------------------------------- 1 | TypeScript 2.3 and later support a mode of type-checking and reporting errors in `.js` files with `--checkJs`. 2 | 3 | You can skip checking some files by adding `// @ts-nocheck` comment to them; conversely you can choose to check only a few `.js` files by adding `// @ts-check` comment to them without setting `--checkJs`. 4 | You can also ignore errors on specific lines by adding `// @ts-ignore` on the preceding line. 5 | 6 | Here are some notable differences on how checking work in `.js` file from `.ts` file: 7 | 8 | ## Using types in JSDoc 9 | 10 | In a `.js` file, types can often be inferred just like in `.ts` files. 11 | Likewise, when types can't be inferred, they can be specified using JSDoc the same way that type annotations do in a `.ts` file. 12 | 13 | JSDoc annotations adorning a declaration will be used to set the type of that declaration. For example: 14 | 15 | ```js 16 | /** @type {number} */ 17 | var x; 18 | 19 | x = 0; // OK 20 | x = false; // Error: boolean is not assignable to number 21 | ``` 22 | 23 | You can find the full list of supported JSDoc patterns in the [JSDoc support in JavaScript documentation](https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-in-JavaScript). 24 | 25 | ## Property declaration inferred from assignments in class bodies 26 | 27 | ES2015/ES6 does not have a means for declaring properties on classes. Properties are dynamically assigned, just like in the case of object literals. 28 | 29 | In a `.js` file property declarations are inferred from assignments to the properties inside the class body. The type of properties is the union of the types of all the right-hand values in these assignments. Properties defined in the constructor are always assumed to exist, where as ones defined in methods, getters, or setters are considered optional. 30 | 31 | Adorn property assignments with JSDoc to specify the type of the property as needed. For instance: 32 | 33 | ```js 34 | class C { 35 | constructor() { 36 | /** @type {number | undefined} */ 37 | this.prop = undefined; 38 | } 39 | } 40 | 41 | 42 | let c = new C(); 43 | c.prop = 0; // OK 44 | c.prop = "string"; // Error: string is not assignable to number|undefined 45 | ``` 46 | 47 | If properties are never set in the class body, they are considered unknown. If your class has properties that are only read from, consider adding an initialization in the constructor to undefined, e.g. `this.prop = undefined;`. 48 | 49 | ## CommonJS module input support 50 | 51 | In a `.js` files CommonJS module format is allowed as an input module format. Assignments to `exports`, and `module.exports` are recognized as export declarations. Similarly, `require` function calls are recognized as module imports. For example: 52 | 53 | ```ts 54 | // import module "fs" 55 | const fs = require("fs"); 56 | 57 | 58 | // export function readFile 59 | module.exports.readFile = function(f) { 60 | return fs.readFileSync(f); 61 | } 62 | ``` 63 | 64 | ## Object literals are open-ended 65 | 66 | By default object literals in variable declarations provide the type of a declaration. No new members can be added that were not specified in the original initialization. This rule is relaxed in a `.js` file; object literals have an open-ended type, allowing adding and looking up properties that were not defined originally. For instance: 67 | 68 | ```js 69 | var obj = { a: 1 }; 70 | obj.b = 2; // Allowed 71 | ``` 72 | 73 | Object literals get a default index signature `[x:string]: any` that allows them to be treated as open maps instead of closed objects. 74 | 75 | Similar to other special JS checking behaviors, this behavior can be changed by specifying a JSDoc type for the variable. For example: 76 | 77 | ```js 78 | /** @type {{a: number}} */ 79 | var obj = { a: 1 }; 80 | obj.b = 2; // Error, type {a: number} does not have property b 81 | ``` 82 | 83 | 84 | ## Function parameters are optional by default 85 | 86 | Since there is no way to specify optionality on parameters in JS (without specifying a default value), all function parameters in `.js` file are considered optional. Calls with fewer arguments are allowed. 87 | 88 | It is important to note that it is an error to call a function with too many arguments. 89 | 90 | For instance: 91 | 92 | ```js 93 | function bar(a, b){ 94 | console.log(a + " " + b); 95 | } 96 | 97 | bar(1); // OK, second argument considered optional 98 | bar(1, 2); 99 | bar(1, 2, 3); // Error, too many arguments 100 | ``` 101 | 102 | JSDoc annotated functions are excluded from this rule. Use JSDoc optional parameter syntax to express optionality. e.g.: 103 | 104 | ```js 105 | /** 106 | * @param {string} [somebody] - Somebody's name. 107 | */ 108 | function sayHello(somebody) { 109 | if (!somebody) { 110 | somebody = 'John Doe'; 111 | } 112 | alert('Hello ' + somebody); 113 | } 114 | 115 | sayHello(); 116 | ``` 117 | 118 | ## Var-args parameter declaration inferred from use of `arguments` 119 | 120 | A function whose body has a reference to the `arguments` reference is implicitly considered to have a var-arg parameter (i.e. `(...arg: any[]) => any`). Use JSDoc var-arg syntax to specify the type of the arguments. 121 | 122 | 123 | ## Unspecified type parameters default to `any` 124 | 125 | An unspecified generic type parameter defaults to `any`. There are few places where this happens: 126 | 127 | #### In extends clause: 128 | 129 | For instance, `React.Component` is defined to have two generic type parameters, `Props` and `State`. 130 | In a `.js` file, there is no legal way to specify these in the extends clause. By default the type arguments will be `any`: 131 | 132 | ```js 133 | import { Component } from "react"; 134 | 135 | class MyComponent extends Component { 136 | render() { 137 | this.props.b; // Allowed, since this.props is of type any 138 | } 139 | } 140 | ``` 141 | 142 | Use JSDoc `@augments` to specify the types explicitly. for instance: 143 | 144 | ```js 145 | import { Component } from "react"; 146 | 147 | /** 148 | * @augments {Component<{a: number}, State>} 149 | */ 150 | class MyComponent extends Component { 151 | render() { 152 | this.props.b; // Error: b does not exist on {a:number} 153 | } 154 | } 155 | ``` 156 | 157 | #### In JSDoc references 158 | 159 | An unspecified generic type argument in JSDoc defaults to any: 160 | 161 | ```js 162 | /** @type{Array} */ 163 | var x = []; 164 | 165 | x.push(1); // OK 166 | x.push("string"); // OK, x is of type Array 167 | 168 | 169 | /** @type{Array.} */ 170 | var y = []; 171 | 172 | y.push(1); // OK 173 | y.push("string"); // Error, string is not assignable to number 174 | 175 | ``` 176 | 177 | #### In function calls 178 | 179 | A call to generic functions uses arguments to infer the generic type parameters. Sometimes this process fails to infer any types, mainly because of lack on inference sources; in these cases, the generic type parameters will default to `any`. For example: 180 | 181 | ```js 182 | var p = new Promise((resolve, reject) => { reject() }); 183 | 184 | p; // Promise; 185 | ``` 186 | -------------------------------------------------------------------------------- /pages/declaration files/Do's and Don'ts.md: -------------------------------------------------------------------------------- 1 | # General Types 2 | 3 | ## `Number`, `String`, `Boolean`, and `Object` 4 | 5 | *Don't* ever use the types `Number`, `String`, `Boolean`, or `Object`. 6 | These types refer to non-primitive boxed objects that are almost never used appropriately in JavaScript code. 7 | 8 | ```ts 9 | /* WRONG */ 10 | function reverse(s: String): String; 11 | ``` 12 | 13 | *Do* use the types `number`, `string`, and `boolean`. 14 | 15 | ```ts 16 | /* OK */ 17 | function reverse(s: string): string; 18 | ``` 19 | 20 | Instead of `Object`, use the non-primitive `object` type ([added in TypeScript 2.2](../release notes/TypeScript 2.2.md#object-type)). 21 | 22 | ## Generics 23 | 24 | *Don't* ever have a generic type which doesn't use its type parameter. 25 | See more details in [TypeScript FAQ page](https://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-type-inference-work-on-this-interface-interface-foot---). 26 | 27 | 28 | 29 | # Callback Types 30 | 31 | ## Return Types of Callbacks 32 | 33 | 34 | 35 | *Don't* use the return type `any` for callbacks whose value will be ignored: 36 | 37 | ```ts 38 | /* WRONG */ 39 | function fn(x: () => any) { 40 | x(); 41 | } 42 | ``` 43 | 44 | *Do* use the return type `void` for callbacks whose value will be ignored: 45 | 46 | ```ts 47 | /* OK */ 48 | function fn(x: () => void) { 49 | x(); 50 | } 51 | ``` 52 | 53 | *Why*: Using `void` is safer because it prevents you from accidently using the return value of `x` in an unchecked way: 54 | 55 | ```ts 56 | function fn(x: () => void) { 57 | var k = x(); // oops! meant to do something else 58 | k.doSomething(); // error, but would be OK if the return type had been 'any' 59 | } 60 | ``` 61 | 62 | ## Optional Parameters in Callbacks 63 | 64 | *Don't* use optional parameters in callbacks unless you really mean it: 65 | 66 | ```ts 67 | /* WRONG */ 68 | interface Fetcher { 69 | getObject(done: (data: any, elapsedTime?: number) => void): void; 70 | } 71 | ``` 72 | 73 | This has a very specific meaning: the `done` callback might be invoked with 1 argument or might be invoked with 2 arguments. 74 | The author probably intended to say that the callback might not care about the `elapsedTime` parameter, 75 | but there's no need to make the parameter optional to accomplish this -- 76 | it's always legal to provide a callback that accepts fewer arguments. 77 | 78 | *Do* write callback parameters as non-optional: 79 | 80 | ```ts 81 | /* OK */ 82 | interface Fetcher { 83 | getObject(done: (data: any, elapsedTime: number) => void): void; 84 | } 85 | ``` 86 | 87 | ## Overloads and Callbacks 88 | 89 | *Don't* write separate overloads that differ only on callback arity: 90 | 91 | ```ts 92 | /* WRONG */ 93 | declare function beforeAll(action: () => void, timeout?: number): void; 94 | declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; 95 | ``` 96 | 97 | *Do* write a single overload using the maximum arity: 98 | 99 | ```ts 100 | /* OK */ 101 | declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; 102 | ``` 103 | 104 | *Why*: It's always legal for a callback to disregard a parameter, so there's no need for the shorter overload. 105 | Providing a shorter callback first allows incorrectly-typed functions to be passed in because they match the first overload. 106 | 107 | # Function Overloads 108 | 109 | ## Ordering 110 | 111 | *Don't* put more general overloads before more specific overloads: 112 | 113 | ```ts 114 | /* WRONG */ 115 | declare function fn(x: any): any; 116 | declare function fn(x: HTMLElement): number; 117 | declare function fn(x: HTMLDivElement): string; 118 | 119 | var myElem: HTMLDivElement; 120 | var x = fn(myElem); // x: any, wat? 121 | ``` 122 | 123 | *Do* sort overloads by putting the more general signatures after more specific signatures: 124 | 125 | ```ts 126 | /* OK */ 127 | declare function fn(x: HTMLDivElement): string; 128 | declare function fn(x: HTMLElement): number; 129 | declare function fn(x: any): any; 130 | 131 | var myElem: HTMLDivElement; 132 | var x = fn(myElem); // x: string, :) 133 | ``` 134 | 135 | *Why*: TypeScript chooses the *first matching overload* when resolving function calls. 136 | When an earlier overload is "more general" than a later one, the later one is effectively hidden and cannot be called. 137 | 138 | ## Use Optional Parameters 139 | 140 | *Don't* write several overloads that differ only in trailing parameters: 141 | 142 | ```ts 143 | /* WRONG */ 144 | interface Example { 145 | diff(one: string): number; 146 | diff(one: string, two: string): number; 147 | diff(one: string, two: string, three: boolean): number; 148 | } 149 | ``` 150 | 151 | *Do* use optional parameters whenever possible: 152 | 153 | ```ts 154 | /* OK */ 155 | interface Example { 156 | diff(one: string, two?: string, three?: boolean): number; 157 | } 158 | ``` 159 | 160 | Note that this collapsing should only occur when all overloads have the same return type. 161 | 162 | *Why*: This is important for two reasons. 163 | 164 | TypeScript resolves signature compatibility by seeing if any signature of the target can be invoked with the arguments of the source, 165 | *and extraneous arguments are allowed*. 166 | This code, for example, exposes a bug only when the signature is correctly written using optional parameters: 167 | 168 | ```ts 169 | function fn(x: (a: string, b: number, c: number) => void) { } 170 | var x: Example; 171 | // When written with overloads, OK -- used first overload 172 | // When written with optionals, correctly an error 173 | fn(x.diff); 174 | ``` 175 | 176 | The second reason is when a consumer uses the "strict null checking" feature of TypeScript. 177 | Because unspecified parameters appear as `undefined` in JavaScript, it's usually fine to pass an explicit `undefined` to a function with optional arguments. 178 | This code, for example, should be OK under strict nulls: 179 | 180 | ```ts 181 | var x: Example; 182 | // When written with overloads, incorrectly an error because of passing 'undefined' to 'string' 183 | // When written with optionals, correctly OK 184 | x.diff("something", true ? undefined : "hour"); 185 | ``` 186 | 187 | ## Use Union Types 188 | 189 | *Don't* write overloads that differ by type in only one argument position: 190 | 191 | ```ts 192 | /* WRONG */ 193 | interface Moment { 194 | utcOffset(): number; 195 | utcOffset(b: number): Moment; 196 | utcOffset(b: string): Moment; 197 | } 198 | ``` 199 | 200 | *Do* use union types whenever possible: 201 | 202 | ```ts 203 | /* OK */ 204 | interface Moment { 205 | utcOffset(): number; 206 | utcOffset(b: number|string): Moment; 207 | } 208 | ``` 209 | 210 | Note that we didn't make `b` optional here because the return types of the signatures differ. 211 | 212 | *Why*: This is important for people who are "passing through" a value to your function: 213 | 214 | ```ts 215 | function fn(x: string): void; 216 | function fn(x: number): void; 217 | function fn(x: number|string) { 218 | // When written with separate overloads, incorrectly an error 219 | // When written with union types, correctly OK 220 | return moment().utcOffset(x); 221 | } 222 | ``` 223 | -------------------------------------------------------------------------------- /pages/release notes/TypeScript 1.7.md: -------------------------------------------------------------------------------- 1 | # `async`/`await` support in ES6 targets (Node v4+) 2 | 3 | TypeScript now supports asynchronous functions for engines that have native support for ES6 generators, e.g. Node v4 and above. 4 | Asynchronous functions are prefixed with the `async` keyword; 5 | `await` suspends the execution until an asynchronous function return promise is fulfilled and unwraps the value from the `Promise` returned. 6 | 7 | ##### Example 8 | 9 | In the following example, each input element will be printed out one at a time with a 400ms delay: 10 | 11 | ```ts 12 | "use strict"; 13 | 14 | // printDelayed is a 'Promise' 15 | async function printDelayed(elements: string[]) { 16 | for (const element of elements) { 17 | await delay(200); 18 | console.log(element); 19 | } 20 | } 21 | 22 | async function delay(milliseconds: number) { 23 | return new Promise(resolve => { 24 | setTimeout(resolve, milliseconds); 25 | }); 26 | } 27 | 28 | printDelayed(["Hello", "beautiful", "asynchronous", "world"]).then(() => { 29 | console.log(); 30 | console.log("Printed every element!"); 31 | }); 32 | ``` 33 | 34 | For more information see [Async Functions](http://blogs.msdn.com/b/typescript/archive/2015/11/03/what-about-async-await.aspx) blog post. 35 | 36 | # Support for `--target ES6` with `--module` 37 | 38 | TypeScript 1.7 adds `ES6` to the list of options available for the `--module` flag and allows you to specify the module output when targeting `ES6`. 39 | This provides more flexibility to target exactly the features you want in specific runtimes. 40 | 41 | ##### Example 42 | 43 | ```json 44 | { 45 | "compilerOptions": { 46 | "module": "amd", 47 | "target": "es6" 48 | } 49 | } 50 | ``` 51 | 52 | # `this`-typing 53 | 54 | It is a common pattern to return the current object (i.e. `this`) from a method to create [fluent-style APIs](https://en.wikipedia.org/wiki/Fluent_interface). 55 | For instance, consider the following `BasicCalculator` module: 56 | 57 | ```ts 58 | export default class BasicCalculator { 59 | public constructor(protected value: number = 0) { } 60 | 61 | public currentValue(): number { 62 | return this.value; 63 | } 64 | 65 | public add(operand: number) { 66 | this.value += operand; 67 | return this; 68 | } 69 | 70 | public subtract(operand: number) { 71 | this.value -= operand; 72 | return this; 73 | } 74 | 75 | public multiply(operand: number) { 76 | this.value *= operand; 77 | return this; 78 | } 79 | 80 | public divide(operand: number) { 81 | this.value /= operand; 82 | return this; 83 | } 84 | } 85 | ``` 86 | 87 | A user could express `2 * 5 + 1` as 88 | 89 | ```ts 90 | import calc from "./BasicCalculator"; 91 | 92 | let v = new calc(2) 93 | .multiply(5) 94 | .add(1) 95 | .currentValue(); 96 | ``` 97 | 98 | This often opens up very elegant ways of writing code; however, there was a problem for classes that wanted to extend from `BasicCalculator`. 99 | Imagine a user wanted to start writing a `ScientificCalculator`: 100 | 101 | ```ts 102 | import BasicCalculator from "./BasicCalculator"; 103 | 104 | export default class ScientificCalculator extends BasicCalculator { 105 | public constructor(value = 0) { 106 | super(value); 107 | } 108 | 109 | public square() { 110 | this.value = this.value ** 2; 111 | return this; 112 | } 113 | 114 | public sin() { 115 | this.value = Math.sin(this.value); 116 | return this; 117 | } 118 | } 119 | ``` 120 | 121 | Because TypeScript used to infer the type `BasicCalculator` for each method in `BasicCalculator` that returned `this`, the type system would forget that it had `ScientificCalculator` whenever using a `BasicCalculator` method. 122 | 123 | For instance: 124 | 125 | ```ts 126 | import calc from "./ScientificCalculator"; 127 | 128 | let v = new calc(0.5) 129 | .square() 130 | .divide(2) 131 | .sin() // Error: 'BasicCalculator' has no 'sin' method. 132 | .currentValue(); 133 | ``` 134 | 135 | This is no longer the case - TypeScript now infers `this` to have a special type called `this` whenever inside an instance method of a class. 136 | The `this` type is written as so, and basically means "the type of the left side of the dot in a method call". 137 | 138 | The `this` type is also useful with intersection types in describing libraries (e.g. Ember.js) that use mixin-style patterns to describe inheritance: 139 | 140 | ```ts 141 | interface MyType { 142 | extend(other: T): this & T; 143 | } 144 | ``` 145 | 146 | # ES7 exponentiation operator 147 | 148 | TypeScript 1.7 supports upcoming [ES7/ES2016 exponentiation operators](https://github.com/rwaldron/exponentiation-operator): `**` and `**=`. 149 | The operators will be transformed in the output to ES3/ES5 using `Math.pow`. 150 | 151 | ##### Example 152 | 153 | ```ts 154 | var x = 2 ** 3; 155 | var y = 10; 156 | y **= 2; 157 | var z = -(4 ** 3); 158 | ``` 159 | 160 | Will generate the following JavaScript output: 161 | 162 | ```js 163 | var x = Math.pow(2, 3); 164 | var y = 10; 165 | y = Math.pow(y, 2); 166 | var z = -(Math.pow(4, 3)); 167 | ``` 168 | 169 | # Improved checking for destructuring object literal 170 | 171 | TypeScript 1.7 makes checking of destructuring patterns with an object literal or array literal initializers less rigid and more intuitive. 172 | 173 | When an object literal is contextually typed by the implied type of an object binding pattern: 174 | 175 | * Properties with default values in the object binding pattern become optional in the object literal. 176 | * Properties in the object binding pattern that have no match in the object literal are required to have a default value in the object binding pattern and are automatically added to the object literal type. 177 | * Properties in the object literal that have no match in the object binding pattern are an error. 178 | 179 | When an array literal is contextually typed by the implied type of an array binding pattern: 180 | 181 | * Elements in the array binding pattern that have no match in the array literal are required to have a default value in the array binding pattern and are automatically added to the array literal type. 182 | 183 | ##### Example 184 | 185 | ```ts 186 | // Type of f1 is (arg?: { x?: number, y?: number }) => void 187 | function f1({ x = 0, y = 0 } = {}) { } 188 | 189 | // And can be called as: 190 | f1(); 191 | f1({}); 192 | f1({ x: 1 }); 193 | f1({ y: 1 }); 194 | f1({ x: 1, y: 1 }); 195 | 196 | // Type of f2 is (arg?: (x: number, y?: number) => void 197 | function f2({ x, y = 0 } = { x: 0 }) { } 198 | 199 | f2(); 200 | f2({}); // Error, x not optional 201 | f2({ x: 1 }); 202 | f2({ y: 1 }); // Error, x not optional 203 | f2({ x: 1, y: 1 }); 204 | ``` 205 | 206 | # Support for decorators when targeting ES3 207 | 208 | Decorators are now allowed when targeting ES3. 209 | TypeScript 1.7 removes the ES5-specific use of `reduceRight` from the `__decorate` helper. 210 | The changes also inline calls `Object.getOwnPropertyDescriptor` and `Object.defineProperty` in a backwards-compatible fashion that allows for a to clean up the emit for ES5 and later by removing various repetitive calls to the aforementioned `Object` methods. -------------------------------------------------------------------------------- /pages/declaration files/Deep Dive.md: -------------------------------------------------------------------------------- 1 | # Definition File Theory: A Deep Dive 2 | 3 | Structuring modules to give the exact API shape you want can be tricky. 4 | For example, we might want a module that can be invoked with or without `new` to produce different types, 5 | has a variety of named types exposed in a hierarchy, 6 | and has some properties on the module object as well. 7 | 8 | By reading this guide, you'll have the tools to write complex definition files that expose a friendly API surface. 9 | This guide focuses on module (or UMD) libraries because the options here are more varied. 10 | 11 | ## Key Concepts 12 | 13 | You can fully understand how to make any shape of definition 14 | by understanding some key concepts of how TypeScript works. 15 | 16 | ### Types 17 | 18 | If you're reading this guide, you probably already roughly know what a type in TypeScript is. 19 | To be more explicit, though, a *type* is introduced with: 20 | 21 | * A type alias declaration (`type sn = number | string;`) 22 | * An interface declaration (`interface I { x: number[]; }`) 23 | * A class declaration (`class C { }`) 24 | * An enum declaration (`enum E { A, B, C }`) 25 | * An `import` declaration which refers to a type 26 | 27 | Each of these declaration forms creates a new type name. 28 | 29 | ### Values 30 | 31 | As with types, you probably already understand what a value is. 32 | Values are runtime names that we can reference in expressions. 33 | For example `let x = 5;` creates a value called `x`. 34 | 35 | Again, being explicit, the following things create values: 36 | 37 | * `let`, `const`, and `var` declarations 38 | * A `namespace` or `module` declaration which contains a value 39 | * An `enum` declaration 40 | * A `class` declaration 41 | * An `import` declaration which refers to a value 42 | * A `function` declaration 43 | 44 | ### Namespaces 45 | 46 | Types can exist in *namespaces*. 47 | For example, if we have the declaration `let x: A.B.C`, 48 | we say that the type `C` comes from the `A.B` namespace. 49 | 50 | This distinction is subtle and important -- here, `A.B` is not necessarily a type or a value. 51 | 52 | ## Simple Combinations: One name, multiple meanings 53 | 54 | Given a name `A`, we might find up to three different meanings for `A`: a type, a value or a namespace. 55 | How the name is interpreted depends on the context in which it is used. 56 | For example, in the declaration `let m: A.A = A;`, 57 | `A` is used first as a namespace, then as a type name, then as a value. 58 | These meanings might end up referring to entirely different declarations! 59 | 60 | This may seem confusing, but it's actually very convenient as long as we don't excessively overload things. 61 | Let's look at some useful aspects of this combining behavior. 62 | 63 | ### Built-in Combinations 64 | 65 | Astute readers will notice that, for example, `class` appeared in both the *type* and *value* lists. 66 | The declaration `class C { }` creates two things: 67 | a *type* `C` which refers to the instance shape of the class, 68 | and a *value* `C` which refers to the constructor function of the class. 69 | Enum declarations behave similarly. 70 | 71 | ### User Combinations 72 | 73 | Let's say we wrote a module file `foo.d.ts`: 74 | 75 | ```ts 76 | export var SomeVar: { a: SomeType }; 77 | export interface SomeType { 78 | count: number; 79 | } 80 | ``` 81 | 82 | Then consumed it: 83 | 84 | ```ts 85 | import * as foo from './foo'; 86 | let x: foo.SomeType = foo.SomeVar.a; 87 | console.log(x.count); 88 | ``` 89 | 90 | This works well enough, but we might imagine that `SomeType` and `SomeVar` were very closely related 91 | such that you'd like them to have the same name. 92 | We can use combining to present these two different objects (the value and the type) under the same name `Bar`: 93 | 94 | ```ts 95 | export var Bar: { a: Bar }; 96 | export interface Bar { 97 | count: number; 98 | } 99 | ``` 100 | 101 | This presents a very good opportunity for destructuring in the consuming code: 102 | 103 | ```ts 104 | import { Bar } from './foo'; 105 | let x: Bar = Bar.a; 106 | console.log(x.count); 107 | ``` 108 | 109 | Again, we've used `Bar` as both a type and a value here. 110 | Note that we didn't have to declare the `Bar` value as being of the `Bar` type -- they're independent. 111 | 112 | ## Advanced Combinations 113 | 114 | Some kinds of declarations can be combined across multiple declarations. 115 | For example, `class C { }` and `interface C { }` can co-exist and both contribute properties to the `C` types. 116 | 117 | This is legal as long as it does not create a conflict. 118 | A general rule of thumb is that values always conflict with other values of the same name unless they are declared as `namespace`s, 119 | types will conflict if they are declared with a type alias declaration (`type s = string`), 120 | and namespaces never conflict. 121 | 122 | Let's see how this can be used. 123 | 124 | ### Adding using an `interface` 125 | 126 | We can add additional members to an `interface` with another `interface` declaration: 127 | 128 | ```ts 129 | interface Foo { 130 | x: number; 131 | } 132 | // ... elsewhere ... 133 | interface Foo { 134 | y: number; 135 | } 136 | let a: Foo = ...; 137 | console.log(a.x + a.y); // OK 138 | ``` 139 | 140 | This also works with classes: 141 | 142 | ```ts 143 | class Foo { 144 | x: number; 145 | } 146 | // ... elsewhere ... 147 | interface Foo { 148 | y: number; 149 | } 150 | let a: Foo = ...; 151 | console.log(a.x + a.y); // OK 152 | ``` 153 | 154 | Note that we cannot add to type aliases (`type s = string;`) using an interface. 155 | 156 | ### Adding using a `namespace` 157 | 158 | A `namespace` declaration can be used to add new types, values, and namespaces in any way which does not create a conflict. 159 | 160 | For example, we can add a static member to a class: 161 | 162 | ```ts 163 | class C { 164 | } 165 | // ... elsewhere ... 166 | namespace C { 167 | export let x: number; 168 | } 169 | let y = C.x; // OK 170 | ``` 171 | 172 | Note that in this example, we added a value to the *static* side of `C` (its constructor function). 173 | This is because we added a *value*, and the container for all values is another value 174 | (types are contained by namespaces, and namespaces are contained by other namespaces). 175 | 176 | We could also add a namespaced type to a class: 177 | 178 | ```ts 179 | class C { 180 | } 181 | // ... elsewhere ... 182 | namespace C { 183 | export interface D { } 184 | } 185 | let y: C.D; // OK 186 | ``` 187 | 188 | In this example, there wasn't a namespace `C` until we wrote the `namespace` declaration for it. 189 | The meaning `C` as a namespace doesn't conflict with the value or type meanings of `C` created by the class. 190 | 191 | Finally, we could perform many different merges using `namespace` declarations. 192 | This isn't a particularly realistic example, but shows all sorts of interesting behavior: 193 | 194 | ```ts 195 | namespace X { 196 | export interface Y { } 197 | export class Z { } 198 | } 199 | 200 | // ... elsewhere ... 201 | namespace X { 202 | export var Y: number; 203 | export namespace Z { 204 | export class C { } 205 | } 206 | } 207 | type X = string; 208 | ``` 209 | 210 | In this example, the first block creates the following name meanings: 211 | 212 | * A value `X` (because the `namespace` declaration contains a value, `Z`) 213 | * A namespace `X` (because the `namespace` declaration contains a type, `Y`) 214 | * A type `Y` in the `X` namespace 215 | * A type `Z` in the `X` namespace (the instance shape of the class) 216 | * A value `Z` that is a property of the `X` value (the constructor function of the class) 217 | 218 | The second block creates the following name meanings: 219 | 220 | * A value `Y` (of type `number`) that is a property of the `X` value 221 | * A namespace `Z` 222 | * A value `Z` that is a property of the `X` value 223 | * A type `C` in the `X.Z` namespace 224 | * A value `C` that is a property of the `X.Z` value 225 | * A type `X` 226 | 227 | ## Using with `export =` or `import` 228 | 229 | An important rule is that `export` and `import` declarations export or import *all meanings* of their targets. 230 | 231 | 232 | -------------------------------------------------------------------------------- /pages/release notes/TypeScript 1.4.md: -------------------------------------------------------------------------------- 1 | # Union types 2 | 3 | ### Overview 4 | 5 | Union types are a powerful way to express a value that can be one of several types. For example, you might have an API for running a program that takes a commandline as either a `string`, a `string[]` or a function that returns a `string`. You can now write: 6 | 7 | ```ts 8 | interface RunOptions { 9 | program: string; 10 | commandline: string[]|string|(() => string); 11 | } 12 | ``` 13 | 14 | Assignment to union types works very intuitively -- anything you could assign to one of the union type's members is assignable to the union: 15 | 16 | ```ts 17 | var opts: RunOptions = /* ... */; 18 | opts.commandline = '-hello world'; // OK 19 | opts.commandline = ['-hello', 'world']; // OK 20 | opts.commandline = [42]; // Error, number is not string or string[] 21 | ``` 22 | 23 | When reading from a union type, you can see any properties that are shared by them: 24 | 25 | ```ts 26 | if (opts.length === 0) { // OK, string and string[] both have 'length' property 27 | console.log("it's empty"); 28 | } 29 | ``` 30 | 31 | Using Type Guards, you can easily work with a variable of a union type: 32 | 33 | ```ts 34 | function formatCommandline(c: string|string[]) { 35 | if (typeof c === 'string') { 36 | return c.trim(); 37 | } 38 | else { 39 | return c.join(' '); 40 | } 41 | } 42 | ``` 43 | 44 | ### Stricter Generics 45 | 46 | With union types able to represent a wide range of type scenarios, we've decided to improve the strictness of certain generic calls. Previously, code like this would (surprisingly) compile without error: 47 | 48 | ```ts 49 | function equal(lhs: T, rhs: T): boolean { 50 | return lhs === rhs; 51 | } 52 | 53 | // Previously: No error 54 | // New behavior: Error, no best common type between 'string' and 'number' 55 | var e = equal(42, 'hello'); 56 | ``` 57 | 58 | With union types, you can now specify the desired behavior at both the function declaration site and the call site: 59 | 60 | ```ts 61 | // 'choose' function where types must match 62 | function choose1(a: T, b: T): T { return Math.random() > 0.5 ? a : b } 63 | var a = choose1('hello', 42); // Error 64 | var b = choose1('hello', 42); // OK 65 | 66 | // 'choose' function where types need not match 67 | function choose2(a: T, b: U): T|U { return Math.random() > 0.5 ? a : b } 68 | var c = choose2('bar', 'foo'); // OK, c: string 69 | var d = choose2('hello', 42); // OK, d: string|number 70 | ``` 71 | 72 | ### Better Type Inference 73 | 74 | Union types also allow for better type inference in arrays and other places where you might have multiple kinds of values in a collection: 75 | 76 | ```ts 77 | var x = [1, 'hello']; // x: Array 78 | x[0] = 'world'; // OK 79 | x[0] = false; // Error, boolean is not string or number 80 | ``` 81 | 82 | # `let` declarations 83 | 84 | In JavaScript, `var` declarations are "hoisted" to the top of their enclosing scope. This can result in confusing bugs: 85 | 86 | ```ts 87 | console.log(x); // meant to write 'y' here 88 | /* later in the same block */ 89 | var x = 'hello'; 90 | ``` 91 | 92 | The new ES6 keyword `let`, now supported in TypeScript, declares a variable with more intuitive "block" semantics. A `let` variable can only be referred to after its declaration, and is scoped to the syntactic block where it is defined: 93 | 94 | ```ts 95 | if (foo) { 96 | console.log(x); // Error, cannot refer to x before its declaration 97 | let x = 'hello'; 98 | } 99 | else { 100 | console.log(x); // Error, x is not declared in this block 101 | } 102 | ``` 103 | 104 | `let` is only available when targeting ECMAScript 6 (`--target ES6`). 105 | 106 | # `const` declarations 107 | 108 | The other new ES6 declaration type supported in TypeScript is `const`. A `const` variable may not be assigned to, and must be initialized where it is declared. This is useful for declarations where you don't want to change the value after its initialization: 109 | 110 | ```ts 111 | const halfPi = Math.PI / 2; 112 | halfPi = 2; // Error, can't assign to a `const` 113 | ``` 114 | 115 | `const` is only available when targeting ECMAScript 6 (`--target ES6`). 116 | 117 | # Template strings 118 | 119 | TypeScript now supports ES6 template strings. These are an easy way to embed arbitrary expressions in strings: 120 | 121 | ```ts 122 | var name = "TypeScript"; 123 | var greeting = `Hello, ${name}! Your name has ${name.length} characters`; 124 | ``` 125 | 126 | When compiling to pre-ES6 targets, the string is decomposed: 127 | 128 | ```js 129 | var name = "TypeScript!"; 130 | var greeting = "Hello, " + name + "! Your name has " + name.length + " characters"; 131 | ``` 132 | 133 | # Type Guards 134 | 135 | A common pattern in JavaScript is to use `typeof` or `instanceof` to examine the type of an expression at runtime. TypeScript now understands these conditions and will change type inference accordingly when used in an `if` block. 136 | 137 | Using `typeof` to test a variable: 138 | 139 | ```ts 140 | var x: any = /* ... */; 141 | if(typeof x === 'string') { 142 | console.log(x.subtr(1)); // Error, 'subtr' does not exist on 'string' 143 | } 144 | // x is still any here 145 | x.unknown(); // OK 146 | ``` 147 | 148 | Using `typeof` with union types and `else`: 149 | 150 | ```ts 151 | var x: string | HTMLElement = /* ... */; 152 | if(typeof x === 'string') { 153 | // x is string here, as shown above 154 | } 155 | else { 156 | // x is HTMLElement here 157 | console.log(x.innerHTML); 158 | } 159 | ``` 160 | 161 | Using `instanceof` with classes and union types: 162 | 163 | ```ts 164 | class Dog { woof() { } } 165 | class Cat { meow() { } } 166 | var pet: Dog|Cat = /* ... */; 167 | if (pet instanceof Dog) { 168 | pet.woof(); // OK 169 | } 170 | else { 171 | pet.woof(); // Error 172 | } 173 | ``` 174 | 175 | # Type Aliases 176 | 177 | You can now define an *alias* for a type using the `type` keyword: 178 | 179 | ```ts 180 | type PrimitiveArray = Array; 181 | type MyNumber = number; 182 | type NgScope = ng.IScope; 183 | type Callback = () => void; 184 | ``` 185 | 186 | Type aliases are exactly the same as their original types; they are simply alternative names. 187 | 188 | # `const enum` (completely inlined enums) 189 | 190 | Enums are very useful, but some programs don't actually need the generated code and would benefit from simply inlining all instances of enum members with their numeric equivalents. The new `const enum` declaration works just like a regular `enum` for type safety, but erases completely at compile time. 191 | 192 | ```ts 193 | const enum Suit { Clubs, Diamonds, Hearts, Spades } 194 | var d = Suit.Diamonds; 195 | ``` 196 | 197 | Compiles to exactly: 198 | 199 | ```js 200 | var d = 1; 201 | ``` 202 | 203 | TypeScript will also now compute enum values when possible: 204 | 205 | ```ts 206 | enum MyFlags { 207 | None = 0, 208 | Neat = 1, 209 | Cool = 2, 210 | Awesome = 4, 211 | Best = Neat | Cool | Awesome 212 | } 213 | var b = MyFlags.Best; // emits var b = 7; 214 | ``` 215 | 216 | # `-noEmitOnError` commandline option 217 | 218 | The default behavior for the TypeScript compiler is to still emit .js files if there were type errors (for example, an attempt to assign a `string` to a `number`). This can be undesirable on build servers or other scenarios where only output from a "clean" build is desired. The new flag `noEmitOnError` prevents the compiler from emitting .js code if there were any errors. 219 | 220 | This is now the default for MSBuild projects; this allows MSBuild incremental build to work as expected, as outputs are only generated on clean builds. 221 | 222 | # AMD Module names 223 | 224 | By default AMD modules are generated anonymous. This can lead to problems when other tools are used to process the resulting modules like a bundlers (e.g. `r.js`). 225 | 226 | The new `amd-module name` tag allows passing an optional module name to the compiler: 227 | 228 | ```ts 229 | //// [amdModule.ts] 230 | /// 231 | export class C { 232 | } 233 | ``` 234 | 235 | Will result in assigning the name `NamedModule` to the module as part of calling the AMD `define`: 236 | 237 | ```js 238 | //// [amdModule.js] 239 | define("NamedModule", ["require", "exports"], function (require, exports) { 240 | var C = (function () { 241 | function C() { 242 | } 243 | return C; 244 | })(); 245 | exports.C = C; 246 | }); 247 | ``` 248 | -------------------------------------------------------------------------------- /pages/tsconfig.json.md: -------------------------------------------------------------------------------- 1 | ## Overview 2 | 3 | The presence of a `tsconfig.json` file in a directory indicates that the directory is the root of a TypeScript project. 4 | The `tsconfig.json` file specifies the root files and the compiler options required to compile the project. 5 | A project is compiled in one of the following ways: 6 | 7 | ## Using tsconfig.json 8 | 9 | * By invoking tsc with no input files, in which case the compiler searches for the `tsconfig.json` file starting in the current directory and continuing up the parent directory chain. 10 | * By invoking tsc with no input files and a `--project` (or just `-p`) command line option that specifies the path of a directory containing a `tsconfig.json` file, or a path to a valid `.json` file containing the configurations. 11 | 12 | When input files are specified on the command line, `tsconfig.json` files are ignored. 13 | 14 | ## Examples 15 | 16 | Example `tsconfig.json` files: 17 | 18 | * Using the `"files"` property 19 | 20 | ```json 21 | { 22 | "compilerOptions": { 23 | "module": "commonjs", 24 | "noImplicitAny": true, 25 | "removeComments": true, 26 | "preserveConstEnums": true, 27 | "sourceMap": true 28 | }, 29 | "files": [ 30 | "core.ts", 31 | "sys.ts", 32 | "types.ts", 33 | "scanner.ts", 34 | "parser.ts", 35 | "utilities.ts", 36 | "binder.ts", 37 | "checker.ts", 38 | "emitter.ts", 39 | "program.ts", 40 | "commandLineParser.ts", 41 | "tsc.ts", 42 | "diagnosticInformationMap.generated.ts" 43 | ] 44 | } 45 | ``` 46 | 47 | * Using the `"include"` and `"exclude"` properties 48 | 49 | ```json 50 | { 51 | "compilerOptions": { 52 | "module": "system", 53 | "noImplicitAny": true, 54 | "removeComments": true, 55 | "preserveConstEnums": true, 56 | "outFile": "../../built/local/tsc.js", 57 | "sourceMap": true 58 | }, 59 | "include": [ 60 | "src/**/*" 61 | ], 62 | "exclude": [ 63 | "node_modules", 64 | "**/*.spec.ts" 65 | ] 66 | } 67 | ``` 68 | 69 | ## Details 70 | 71 | The `"compilerOptions"` property can be omitted, in which case the compiler's defaults are used. See our full list of supported [Compiler Options](./Compiler Options.md). 72 | 73 | The `"files"` property takes a list of relative or absolute file paths. 74 | The `"include"` and `"exclude"` properties take a list of glob-like file patterns. 75 | The supported glob wildcards are: 76 | 77 | * `*` matches zero or more characters (excluding directory separators) 78 | * `?` matches any one character (excluding directory separators) 79 | * `**/` recursively matches any subdirectory 80 | 81 | If a segment of a glob pattern includes only `*` or `.*`, then only files with supported extensions are included (e.g. `.ts`, `.tsx`, and `.d.ts` by default with `.js` and `.jsx` if `allowJs` is set to true). 82 | 83 | If the `"files"` and `"include"` are both left unspecified, the compiler defaults to including all TypeScript (`.ts`, `.d.ts` and `.tsx`) files in the containing directory and subdirectories except those excluded using the `"exclude"` property. JS files (`.js` and `.jsx`) are also included if `allowJs` is set to true. 84 | If the `"files"` or `"include"` properties are specified, the compiler will instead include the union of the files included by those two properties. 85 | Files in the directory specified using the `"outDir"` compiler option are always excluded unless explicitly included via the `"files"` property (even when the "`exclude`" property is specified). 86 | 87 | Files included using `"include"` can be filtered using the `"exclude"` property. 88 | However, files included explicitly using the `"files"` property are always included regardless of `"exclude"`. 89 | The `"exclude"` property defaults to excluding the `node_modules`, `bower_components`, `jspm_packages` and `` directories when not specified. 90 | 91 | Any files that are referenced by files included via the `"files"` or `"include"` properties are also included. 92 | Similarly, if a file `B.ts` is referenced by another file `A.ts`, then `B.ts` cannot be excluded unless the referencing file `A.ts` is also specified in the `"exclude"` list. 93 | 94 | Please note that the compiler does not include files that can be possible outputs; e.g. if the input includes `index.ts`, then `index.d.ts` and `index.js` are excluded. 95 | In general, having files that differ only in extension next to each other is not recomended. 96 | 97 | A `tsconfig.json` file is permitted to be completely empty, which compiles all files included by default (as described above) with the default compiler options. 98 | 99 | Compiler options specified on the command line override those specified in the `tsconfig.json` file. 100 | 101 | ## `@types`, `typeRoots` and `types` 102 | 103 | By default all *visible* "`@types`" packages are included in your compilation. 104 | Packages in `node_modules/@types` of any enclosing folder are considered *visible*; 105 | specifically, that means packages within `./node_modules/@types/`, `../node_modules/@types/`, `../../node_modules/@types/`, and so on. 106 | 107 | If `typeRoots` is specified, *only* packages under `typeRoots` will be included. 108 | For example: 109 | 110 | ```json 111 | { 112 | "compilerOptions": { 113 | "typeRoots" : ["./typings"] 114 | } 115 | } 116 | ``` 117 | 118 | This config file will include *all* packages under `./typings`, and no packages from `./node_modules/@types`. 119 | 120 | If `types` is specified, only packages listed will be included. 121 | For instance: 122 | 123 | ```json 124 | { 125 | "compilerOptions": { 126 | "types" : ["node", "lodash", "express"] 127 | } 128 | } 129 | ``` 130 | 131 | This `tsconfig.json` file will *only* include `./node_modules/@types/node`, `./node_modules/@types/lodash` and `./node_modules/@types/express`. 132 | Other packages under `node_modules/@types/*` will not be included. 133 | 134 | Specify `"types": []` to disable automatic inclusion of `@types` packages. 135 | 136 | Keep in mind that automatic inclusion is only important if you're using files with global declarations (as opposed to files declared as modules). 137 | If you use an `import "foo"` statement, for instance, TypeScript may still look through `node_modules` & `node_modules/@types` folders to find the `foo` package. 138 | 139 | ## Configuration inheritance with `extends` 140 | 141 | A `tsconfig.json` file can inherit configurations from another file using the `extends` property. 142 | 143 | The `extends` is a top-level property in `tsconfig.json` (alongside `compilerOptions`, `files`, `include`, and `exclude`). 144 | `extends`' value is a string containing a path to another configuration file to inherit from. 145 | 146 | The configuration from the base file are loaded first, then overridden by those in the inheriting config file. 147 | If a circularity is encountered, we report an error. 148 | 149 | `files`, `include` and `exclude` from the inheriting config file *overwrite* those from the base config file. 150 | 151 | All relative paths found in the configuration file will be resolved relative to the configuration file they originated in. 152 | 153 | For example: 154 | 155 | `configs/base.json`: 156 | 157 | ```json 158 | { 159 | "compilerOptions": { 160 | "noImplicitAny": true, 161 | "strictNullChecks": true 162 | } 163 | } 164 | ``` 165 | 166 | `tsconfig.json`: 167 | 168 | ```json 169 | { 170 | "extends": "./configs/base", 171 | "files": [ 172 | "main.ts", 173 | "supplemental.ts" 174 | ] 175 | } 176 | ``` 177 | 178 | `tsconfig.nostrictnull.json`: 179 | 180 | ```json 181 | { 182 | "extends": "./tsconfig", 183 | "compilerOptions": { 184 | "strictNullChecks": false 185 | } 186 | } 187 | ``` 188 | 189 | ## `compileOnSave` 190 | 191 | Setting a top-level property `compileOnSave` signals to the IDE to generate all files for a given tsconfig.json upon saving. 192 | 193 | ```json 194 | { 195 | "compileOnSave": true, 196 | "compilerOptions": { 197 | "noImplicitAny" : true 198 | } 199 | } 200 | ``` 201 | 202 | This feature is currently supported in Visual Studio 2015 with TypeScript 1.8.4 and above, and [atom-typescript](https://github.com/TypeStrong/atom-typescript#compile-on-save) plugin. 203 | 204 | ## Schema 205 | 206 | Schema can be found at: [http://json.schemastore.org/tsconfig](http://json.schemastore.org/tsconfig) 207 | -------------------------------------------------------------------------------- /pages/release notes/TypeScript 2.2.md: -------------------------------------------------------------------------------- 1 | # Support for Mix-in classes 2 | 3 | TypeScript 2.2 adds support for the ECMAScript 2015 mixin class pattern (see [MDN Mixin description](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Mix-ins) and ["Real" Mixins with JavaScript Classes](http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/) for more details) as well as rules for combining mixin construct signatures with regular construct signatures in intersection types. 4 | 5 | ##### First some terminology 6 | 7 | A **mixin constructor type** refers to a type that has a single construct signature with a single rest argument of type `any[]` and an object-like return type. For example, given an object-like type `X`, `new (...args: any[]) => X` is a mixin constructor type with an instance type `X`. 8 | 9 | A **mixin class** is a class declaration or expression that `extends` an expression of a type parameter type. The following rules apply to mixin class declarations: 10 | 11 | * The type parameter type of the `extends` expression must be constrained to a mixin constructor type. 12 | * The constructor of a mixin class (if any) must have a single rest parameter of type `any[]` and must use the spread operator to pass those parameters as arguments in a `super(...args)` call. 13 | 14 | Given an expression `Base` of a parametric type `T` with a constraint `X`, a mixin class `class C extends Base {...}` is processed as if `Base` had type `X` and the resulting type is the intersection `typeof C & T`. 15 | In other words, a mixin class is represented as an intersection between the mixin class constructor type and the parametric base class constructor type. 16 | 17 | When obtaining the construct signatures of an intersection type that contains mixin constructor types, the mixin construct signatures are discarded and their instance types are mixed into the return types of the other construct signatures in the intersection type. 18 | For example, the intersection type `{ new(...args: any[]) => A } & { new(s: string) => B }` has a single construct signature `new(s: string) => A & B`. 19 | 20 | ##### Putting all of the above rules together in an example 21 | 22 | ```ts 23 | class Point { 24 | constructor(public x: number, public y: number) {} 25 | } 26 | 27 | class Person { 28 | constructor(public name: string) {} 29 | } 30 | 31 | type Constructor = new(...args: any[]) => T; 32 | 33 | function Tagged>(Base: T) { 34 | return class extends Base { 35 | _tag: string; 36 | constructor(...args: any[]) { 37 | super(...args); 38 | this._tag = ""; 39 | } 40 | } 41 | } 42 | 43 | const TaggedPoint = Tagged(Point); 44 | 45 | let point = new TaggedPoint(10, 20); 46 | point._tag = "hello"; 47 | 48 | class Customer extends Tagged(Person) { 49 | accountBalance: number; 50 | } 51 | 52 | let customer = new Customer("Joe"); 53 | customer._tag = "test"; 54 | customer.accountBalance = 0; 55 | ``` 56 | 57 | Mixin classes can constrain the types of classes they can mix into by specifying a construct signature return type in the constraint for the type parameter. 58 | For example, the following `WithLocation` function implements a subclass factory that adds a `getLocation` method to any class that satisfies the `Point` interface (i.e. that has `x` and `y` properties of type `number`). 59 | 60 | ```ts 61 | interface Point { 62 | x: number; 63 | y: number; 64 | } 65 | 66 | const WithLocation = >(Base: T) => 67 | class extends Base { 68 | getLocation(): [number, number] { 69 | return [this.x, this.y]; 70 | } 71 | } 72 | ``` 73 | 74 | # `object` type 75 | 76 | TypeScript did not have a type that represents the non-primitive type, i.e. any thing that is not `number`, `string`, `boolean`, `symbol`, `null`, or `undefined`. Enter the new `object` type. 77 | 78 | With `object` type, APIs like `Object.create` can be better represented. For example: 79 | 80 | ```ts 81 | declare function create(o: object | null): void; 82 | 83 | create({ prop: 0 }); // OK 84 | create(null); // OK 85 | 86 | create(42); // Error 87 | create("string"); // Error 88 | create(false); // Error 89 | create(undefined); // Error 90 | ``` 91 | 92 | # Support for `new.target` 93 | 94 | The `new.target` meta-property is new syntax introduced in ES2015. 95 | When an instance of a constructor is created via `new`, the value of `new.target` is set to be a reference to the constructor function initially used to allocate the instance. 96 | If a function is called rather than constructed via `new`, `new.target` is set to `undefined`. 97 | 98 | `new.target` comes in handy when `Object.setPrototypeOf` or `__proto__` needs to be set in a class constructor. One such use case is inheriting from `Error` in NodeJS v4 and higher. 99 | 100 | ##### Example 101 | 102 | ```ts 103 | class CustomError extends Error { 104 | constructor(message?: string) { 105 | super(message); // 'Error' breaks prototype chain here 106 | Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain 107 | } 108 | } 109 | ``` 110 | 111 | This results in the generated JS 112 | 113 | ```js 114 | var CustomError = (function (_super) { 115 | __extends(CustomError, _super); 116 | function CustomError() { 117 | var _newTarget = this.constructor; 118 | var _this = _super.apply(this, arguments); // 'Error' breaks prototype chain here 119 | _this.__proto__ = _newTarget.prototype; // restore prototype chain 120 | return _this; 121 | } 122 | return CustomError; 123 | })(Error); 124 | ``` 125 | 126 | `new.target` also comes in handy for writing constructable functions, for example: 127 | 128 | ```ts 129 | function f() { 130 | if (new.target) { /* called via 'new' */ } 131 | } 132 | ``` 133 | 134 | Which translates to: 135 | 136 | ```js 137 | function f() { 138 | var _newTarget = this && this instanceof f ? this.constructor : void 0; 139 | if (_newTarget) { /* called via 'new' */ } 140 | } 141 | ``` 142 | 143 | # Better checking for `null`/`undefined` in operands of expressions 144 | 145 | TypeScript 2.2 improves checking of nullable operands in expressions. Specifically, these are now flagged as errors: 146 | 147 | * If either operand of a `+` operator is nullable, and neither operand is of type `any` or `string`. 148 | * If either operand of a `-`, `*`, `**`, `/`, `%`, `<<`, `>>`, `>>>`, `&`, `|`, or `^` operator is nullable. 149 | * If either operand of a `<`, `>`, `<=`, `>=`, or `in` operator is nullable. 150 | * If the right operand of an `instanceof` operator is nullable. 151 | * If the operand of a `+`, `-`, `~`, `++`, or `--` unary operator is nullable. 152 | 153 | An operand is considered nullable if the type of the operand is `null` or `undefined` or a union type that includes `null` or `undefined`. 154 | Note that the union type case only only occurs in `--strictNullChecks` mode because `null` and `undefined` disappear from unions in classic type checking mode. 155 | 156 | # Dotted property for types with string index signatures 157 | 158 | Types with a string index signature can be indexed using the `[]` notation, but were not allowed to use the `.`. 159 | Starting with TypeScript 2.2 using either should be allowed. 160 | 161 | ```ts 162 | interface StringMap { 163 | [x: string]: T; 164 | } 165 | 166 | const map: StringMap; 167 | 168 | map["prop1"] = 1; 169 | map.prop2 = 2; 170 | 171 | ``` 172 | 173 | This only apply to types with an *explicit* string index signature. 174 | It is still an error to access unknown properties on a type using `.` notation. 175 | 176 | # Support for spread operator on JSX element children 177 | 178 | TypeScript 2.2 adds support for using spread on a JSX element children. 179 | Please see [facebook/jsx#57](https://github.com/facebook/jsx/issues/57) for more details. 180 | 181 | ##### Example 182 | 183 | ```ts 184 | function Todo(prop: { key: number, todo: string }) { 185 | return
{prop.key.toString() + prop.todo}
; 186 | } 187 | 188 | function TodoList({ todos }: TodoListProps) { 189 | return
190 | {...todos.map(todo => )} 191 |
; 192 | } 193 | 194 | let x: TodoListProps; 195 | 196 | 197 | ``` 198 | 199 | # New `jsx: react-native` 200 | 201 | React-native build pipeline expects all files to have a `.js` extensions even if the file contains JSX syntax. 202 | The new `--jsx` value `react-native` will persevere the JSX syntax in the output file, but give it a `.js` extension. 203 | -------------------------------------------------------------------------------- /pages/Compiler Options in MSBuild.md: -------------------------------------------------------------------------------- 1 | ## Overview 2 | 3 | Compiler options can be specified using MSBuild properties within an MSBuild project. 4 | 5 | ## Example 6 | 7 | ```XML 8 | 9 | false 10 | true 11 | 12 | 13 | true 14 | false 15 | 16 | 19 | ``` 20 | 21 | ## Mappings 22 | 23 | Compiler Option | MSBuild Property Name | Allowed Values 24 | ---------------------------------------------|--------------------------------------------|----------------- 25 | `--allowJs` | *Not supported in MSBuild* | 26 | `--allowSyntheticDefaultImports` | TypeScriptAllowSyntheticDefaultImports | boolean 27 | `--allowUnreachableCode` | TypeScriptAllowUnreachableCode | boolean 28 | `--allowUnusedLabels` | TypeScriptAllowUnusedLabels | boolean 29 | `--alwaysStrict` | TypeScriptAlwaysStrict | boolean 30 | `--baseUrl` | TypeScriptBaseUrl | File path 31 | `--charset` | TypeScriptCharset | 32 | `--declaration` | TypeScriptGeneratesDeclarations | boolean 33 | `--declarationDir` | TypeScriptDeclarationDir | File path 34 | `--diagnostics` | *Not supported in MSBuild* | 35 | `--disableSizeLimit` | *Not supported in MSBuild* | 36 | `--emitBOM` | TypeScriptEmitBOM | boolean 37 | `--emitDecoratorMetadata` | TypeScriptEmitDecoratorMetadata | boolean 38 | `--experimentalAsyncFunctions` | TypeScriptExperimentalAsyncFunctions | boolean 39 | `--experimentalDecorators` | TypeScriptExperimentalDecorators | boolean 40 | `--forceConsistentCasingInFileNames` | TypeScriptForceConsistentCasingInFileNames | boolean 41 | `--help` | *Not supported in MSBuild* | 42 | `--importHelpers` | TypeScriptImportHelpers | boolean 43 | `--inlineSourceMap` | TypeScriptInlineSourceMap | boolean 44 | `--inlineSources` | TypeScriptInlineSources | boolean 45 | `--init` | *Not supported in MSBuild* | 46 | `--isolatedModules` | TypeScriptIsolatedModules | boolean 47 | `--jsx` | TypeScriptJSXEmit | `React` or `Preserve` 48 | `--jsxFactory` | TypeScriptJSXFactory | qualified name 49 | `--lib` | TypeScriptLib | Comma-separated list of strings 50 | `--listEmittedFiles` | *Not supported in MSBuild* | 51 | `--listFiles` | *Not supported in MSBuild* | 52 | `--locale` | *automatic* | Automatically set to PreferredUILang value 53 | `--mapRoot` | TypeScriptMapRoot | File path 54 | `--maxNodeModuleJsDepth` | *Not supported in MSBuild* | 55 | `--module` | TypeScriptModuleKind | `AMD`, `CommonJs`, `UMD`, `System` or `ES6` 56 | `--moduleResolution` | TypeScriptModuleResolution | `Classic` or `Node` 57 | `--newLine` | TypeScriptNewLine | `CRLF` or `LF` 58 | `--noEmit` | *Not supported in MSBuild* | 59 | `--noEmitHelpers` | TypeScriptNoEmitHelpers | boolean 60 | `--noEmitOnError` | TypeScriptNoEmitOnError | boolean 61 | `--noFallthroughCasesInSwitch` | TypeScriptNoFallthroughCasesInSwitch | boolean 62 | `--noImplicitAny` | TypeScriptNoImplicitAny | boolean 63 | `--noImplicitReturns` | TypeScriptNoImplicitReturns | boolean 64 | `--noImplicitThis` | TypeScriptNoImplicitThis | boolean 65 | `--noImplicitUseStrict` | TypeScriptNoImplicitUseStrict | boolean 66 | `--noStrictGenericChecks` | TypeScriptNoStrictGenericChecks | boolean 67 | `--noUnusedLocals` | TypeScriptNoUnusedLocals | boolean 68 | `--noUnusedParameters` | TypeScriptNoUnusedParameters | boolean 69 | `--noLib` | TypeScriptNoLib | boolean 70 | `--noResolve` | TypeScriptNoResolve | boolean 71 | `--out` | TypeScriptOutFile | File path 72 | `--outDir` | TypeScriptOutDir | File path 73 | `--outFile` | TypeScriptOutFile | File path 74 | `--paths` | *Not supported in MSBuild* | 75 | `--preserveConstEnums` | TypeScriptPreserveConstEnums | boolean 76 | `--preserveSymlinks` | TypeScriptPreserveSymlinks | boolean 77 | `--listEmittedFiles` | *Not supported in MSBuild* | 78 | `--pretty` | *Not supported in MSBuild* | 79 | `--reactNamespace` | TypeScriptReactNamespace | string 80 | `--removeComments` | TypeScriptRemoveComments | boolean 81 | `--rootDir` | TypeScriptRootDir | File path 82 | `--rootDirs` | *Not supported in MSBuild* | 83 | `--skipLibCheck` | TypeScriptSkipLibCheck | boolean 84 | `--skipDefaultLibCheck` | TypeScriptSkipDefaultLibCheck | boolean 85 | `--sourceMap` | TypeScriptSourceMap | File path 86 | `--sourceRoot` | TypeScriptSourceRoot | File path 87 | `--strict` | TypeScriptStrict | boolean 88 | `--strictFunctionTypes` | TypeScriptStrictFunctionTypes | boolean 89 | `--strictNullChecks` | TypeScriptStrictNullChecks | boolean 90 | `--stripInternal` | TypeScriptStripInternal | boolean 91 | `--suppressExcessPropertyErrors` | TypeScriptSuppressExcessPropertyErrors | boolean 92 | `--suppressImplicitAnyIndexErrors` | TypeScriptSuppressImplicitAnyIndexErrors | boolean 93 | `--target` | TypeScriptTarget | `ES3`, `ES5`, or `ES6` 94 | `--traceResolution` | *Not supported in MSBuild* | 95 | `--types` | *Not supported in MSBuild* | 96 | `--typeRoots` | *Not supported in MSBuild* | 97 | `--watch` | *Not supported in MSBuild* | 98 | *MSBuild only option* | TypeScriptAdditionalFlags | *Any compiler option* 99 | 100 | ## What is supported in my version of Visual Studio? 101 | 102 | Look in your `C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets` file. 103 | The authoritative mappings between MSBuild XML tags and `tsc` compiler options live in there. 104 | 105 | ## ToolsVersion 106 | 107 | The value of `1.7` property in the project file identifies the compiler version to use to build (1.7 in this example). 108 | This allows a project to build against the save versions of the compiler on different machines. 109 | 110 | If `TypeScriptToolsVersion` is not specified, the latest compiler version installed on the machine will be used to build. 111 | 112 | Users using newer versions of TS, will see a prompt to upgrade their project on first load. 113 | 114 | ## TypeScriptCompileBlocked 115 | 116 | If you are using a different build tool to build your project (e.g. gulp, grunt , etc.) and VS for the development and debugging experience, set `true` in your project. 117 | This should give you all the editing support, but not the build when you hit F5. 118 | -------------------------------------------------------------------------------- /pages/tutorials/React & Webpack.md: -------------------------------------------------------------------------------- 1 | This guide will teach you how to wire up TypeScript with [React](http://facebook.github.io/react/) and [webpack](http://webpack.github.io/). 2 | 3 | If you're starting a brand new project, take a look at the [React Quick Start guide](/samples/index.html) first. 4 | 5 | Otherwise, we assume that you're already using [Node.js](https://nodejs.org/) with [npm](https://www.npmjs.com/). 6 | 7 | # Lay out the project 8 | 9 | Let's start out with a new directory. 10 | We'll name it `proj` for now, but you can change it to whatever you want. 11 | 12 | ```shell 13 | mkdir proj 14 | cd proj 15 | ``` 16 | 17 | To start, we're going to structure our project in the following way: 18 | 19 | ```text 20 | proj/ 21 | ├─ dist/ 22 | └─ src/ 23 | └─ components/ 24 | ``` 25 | 26 | TypeScript files will start out in your `src` folder, run through the TypeScript compiler, then webpack, and end up in a `bundle.js` file in `dist`. 27 | Any components that we write will go in the `src/components` folder. 28 | 29 | Let's scaffold this out: 30 | 31 | ```shell 32 | mkdir src 33 | cd src 34 | mkdir components 35 | cd .. 36 | ``` 37 | 38 | Webpack will eventually generate the `dist` directory for us. 39 | 40 | # Initialize the project 41 | 42 | Now we'll turn this folder into an npm package. 43 | 44 | ```shell 45 | npm init 46 | ``` 47 | 48 | You'll be given a series of prompts, but you can feel free to use the defaults. 49 | You can always go back and change these in the `package.json` file that's been generated for you. 50 | 51 | # Install our dependencies 52 | 53 | First ensure Webpack is installed globally. 54 | 55 | ```shell 56 | npm install -g webpack 57 | ``` 58 | 59 | Webpack is a tool that will bundle your code and optionally all of its dependencies into a single `.js` file. 60 | 61 | Let's now add React and React-DOM, along with their declaration files, as dependencies to your `package.json` file: 62 | 63 | ```shell 64 | npm install --save react react-dom @types/react @types/react-dom 65 | ``` 66 | 67 | That `@types/` prefix means that we also want to get the declaration files for React and React-DOM. 68 | Usually when you import a path like `"react"`, it will look inside of the `react` package itself; 69 | however, not all packages include declaration files, so TypeScript also looks in the `@types/react` package as well. 70 | You'll see that we won't even have to think about this later on. 71 | 72 | Next, we'll add development-time dependencies on [awesome-typescript-loader](https://www.npmjs.com/package/awesome-typescript-loader) and [source-map-loader](https://www.npmjs.com/package/source-map-loader). 73 | 74 | ```shell 75 | npm install --save-dev typescript awesome-typescript-loader source-map-loader 76 | ``` 77 | 78 | Both of these dependencies will let TypeScript and webpack play well together. 79 | awesome-typescript-loader helps Webpack compile your TypeScript code using the TypeScript's standard configuration file named `tsconfig.json`. 80 | source-map-loader uses any sourcemap outputs from TypeScript to inform webpack when generating *its own* sourcemaps. 81 | This will allow you to debug your final output file as if you were debugging your original TypeScript source code. 82 | 83 | Please note that awesome-typescript-loader is not the only loader for typescript. 84 | You could instead use [ts-loader](https://github.com/TypeStrong/ts-loader). 85 | Read about the differences between them [here](https://github.com/s-panferov/awesome-typescript-loader#differences-between-ts-loader) 86 | 87 | Notice that we installed TypeScript as a development dependency. 88 | We could also have linked TypeScript to a global copy with `npm link typescript`, but this is a less common scenario. 89 | 90 | # Add a TypeScript configuration file 91 | 92 | You'll want to bring your TypeScript files together - both the code you'll be writing as well as any necessary declaration files. 93 | 94 | To do this, you'll need to create a `tsconfig.json` which contains a list of your input files as well as all your compilation settings. 95 | Simply create a new file in your project root named `tsconfig.json` and fill it with the following contents: 96 | 97 | ```json 98 | { 99 | "compilerOptions": { 100 | "outDir": "./dist/", 101 | "sourceMap": true, 102 | "noImplicitAny": true, 103 | "module": "commonjs", 104 | "target": "es5", 105 | "jsx": "react" 106 | }, 107 | "include": [ 108 | "./src/**/*" 109 | ] 110 | } 111 | ``` 112 | 113 | You can learn more about `tsconfig.json` files [here](../tsconfig.json.md). 114 | 115 | # Write some code 116 | 117 | Let's write our first TypeScript file using React. 118 | First, create a file named `Hello.tsx` in `src/components` and write the following: 119 | 120 | ```ts 121 | import * as React from "react"; 122 | 123 | export interface HelloProps { compiler: string; framework: string; } 124 | 125 | export const Hello = (props: HelloProps) =>

Hello from {props.compiler} and {props.framework}!

; 126 | ``` 127 | 128 | Note that while this example uses [stateless functional components](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions), we could also make our example a little *classier* as well. 129 | 130 | ```ts 131 | import * as React from "react"; 132 | 133 | export interface HelloProps { compiler: string; framework: string; } 134 | 135 | // 'HelloProps' describes the shape of props. 136 | // State is never set so we use the '{}' type. 137 | export class Hello extends React.Component { 138 | render() { 139 | return

Hello from {this.props.compiler} and {this.props.framework}!

; 140 | } 141 | } 142 | ``` 143 | 144 | Next, let's create an `index.tsx` in `src` with the following source: 145 | 146 | ```ts 147 | import * as React from "react"; 148 | import * as ReactDOM from "react-dom"; 149 | 150 | import { Hello } from "./components/Hello"; 151 | 152 | ReactDOM.render( 153 | , 154 | document.getElementById("example") 155 | ); 156 | ``` 157 | 158 | We just imported our `Hello` component into `index.tsx`. 159 | Notice that unlike with `"react"` or `"react-dom"`, we used a *relative path* to `Hello.tsx` - this is important. 160 | If we hadn't, TypeScript would've instead tried looking in our `node_modules` folder. 161 | 162 | We'll also need a page to display our `Hello` component. 163 | Create a file at the root of `proj` named `index.html` with the following contents: 164 | 165 | ```html 166 | 167 | 168 | 169 | 170 | Hello React! 171 | 172 | 173 |
174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | ``` 184 | 185 | Notice that we're including files from within `node_modules`. 186 | React and React-DOM's npm packages include standalone `.js` files that you can include in a web page, and we're referencing them directly to get things moving faster. 187 | Feel free to copy these files to another directory, or alternatively, host them on a content delivery network (CDN). 188 | Facebook makes CDN-hosted versions of React available, and you can [read more about that here](http://facebook.github.io/react/downloads.html#development-vs.-production-builds). 189 | 190 | # Create a webpack configuration file 191 | 192 | Create a `webpack.config.js` file at the root of the project directory. 193 | 194 | ```js 195 | module.exports = { 196 | entry: "./src/index.tsx", 197 | output: { 198 | filename: "bundle.js", 199 | path: __dirname + "/dist" 200 | }, 201 | 202 | // Enable sourcemaps for debugging webpack's output. 203 | devtool: "source-map", 204 | 205 | resolve: { 206 | // Add '.ts' and '.tsx' as resolvable extensions. 207 | extensions: [".ts", ".tsx", ".js", ".json"] 208 | }, 209 | 210 | module: { 211 | rules: [ 212 | // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'. 213 | { test: /\.tsx?$/, loader: "awesome-typescript-loader" }, 214 | 215 | // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'. 216 | { enforce: "pre", test: /\.js$/, loader: "source-map-loader" } 217 | ] 218 | }, 219 | 220 | // When importing a module whose path matches one of the following, just 221 | // assume a corresponding global variable exists and use that instead. 222 | // This is important because it allows us to avoid bundling all of our 223 | // dependencies, which allows browsers to cache those libraries between builds. 224 | externals: { 225 | "react": "React", 226 | "react-dom": "ReactDOM" 227 | }, 228 | }; 229 | ``` 230 | 231 | You might be wondering about that `externals` field. 232 | We want to avoid bundling all of React into the same file, since this increases compilation time and browsers will typically be able to cache a library if it doesn't change. 233 | 234 | Ideally, we'd just import the React module from within the browser, but most browsers still don't quite support modules yet. 235 | Instead libraries have traditionally made themselves available using a single global variable like `jQuery` or `_`. 236 | This is called the "namespace pattern", and webpack allows us to continue leveraging libraries written that way. 237 | With our entry for `"react": "React"`, webpack will work its magic to make any import of `"react"` load from the `React` variable. 238 | 239 | You can learn more about configuring webpack [here](https://webpack.js.org/concepts). 240 | 241 | # Putting it all together 242 | 243 | Just run: 244 | 245 | ```shell 246 | webpack 247 | ``` 248 | 249 | Now open up `index.html` in your favorite browser and everything should be ready to use! 250 | You should see a page that says "Hello from TypeScript and React!" 251 | -------------------------------------------------------------------------------- /pages/Enums.md: -------------------------------------------------------------------------------- 1 | # Enums 2 | 3 | Enums allow us to define a set of named constants. 4 | Using enums can make it easier to document intent, or create a set of distinct cases. 5 | TypeScript provides both numeric and string-based enums. 6 | 7 | ## Numeric enums 8 | 9 | We'll first start off with numeric enums, which are probably more familiar if you're coming from other languages. 10 | An enum can be defined using the `enum` keyword. 11 | 12 | ```ts 13 | enum Direction { 14 | Up = 1, 15 | Down, 16 | Left, 17 | Right, 18 | } 19 | ``` 20 | 21 | Above, we have a numeric enum where `Up` is initialized with `1`. 22 | All of the following members are auto-incremented from that point on. 23 | In other words, `Direction.Up` has the value `1`, `Down` has `2`, `Left` has `3`, and `Right` has `4`. 24 | 25 | If we wanted, we could leave off the initializers entirely: 26 | 27 | ```ts 28 | enum Direction { 29 | Up, 30 | Down, 31 | Left, 32 | Right, 33 | } 34 | ``` 35 | 36 | Here, `Up` would have the value `0`, `Down` would have `1`, etc. 37 | This auto-incrementing behavior is useful for cases where we might not care about the member values themselves, but do care that each value is distinct from other values in the same enum. 38 | 39 | Using an enum is simple: just access any member as a property off of the enum itself, and declare types using the name of the enum: 40 | 41 | ```ts 42 | enum Response { 43 | No = 0, 44 | Yes = 1, 45 | } 46 | 47 | function respond(recipient: string, message: Response): void { 48 | // ... 49 | } 50 | 51 | respond("Princess Caroline", Response.Yes) 52 | ``` 53 | 54 | Numeric enums can be mixed in [computed and constant members (see below)](#computed-and-constant-members). 55 | The short story is, enums without initializers either need to be first, or have to come after numeric enums initialized with numeric constants or other constant enum members. 56 | In other words, the following isn't allowed: 57 | 58 | ```ts 59 | enum E { 60 | A = getSomeValue(), 61 | B, // error! 'A' is not constant-initialized, so 'B' needs an initializer 62 | } 63 | ``` 64 | 65 | ## String enums 66 | 67 | String enums are a similar concept, but have some subtle [runtime differences](#enums-at-runtime) as documented below. 68 | In a string enum, each member has to be constant-initialized with a string literal, or with another string enum member. 69 | 70 | ```ts 71 | enum Direction { 72 | Up = "UP", 73 | Down = "DOWN", 74 | Left = "LEFT", 75 | Right = "RIGHT", 76 | } 77 | ``` 78 | 79 | While string enums don't have auto-incrementing behavior, string enums have the benefit that they "serialize" well. 80 | In other words, if you were debugging and had to read the runtime value of a numeric enum, the value is often opaque - it doesn't convey any useful meaning on its own (though [reverse mapping](#enums-at-runtime) can often help), string enums allow you to give a meaningful and readable value when your code runs, independent of the name of the enum member itself. 81 | 82 | ## Heterogeneous enums 83 | 84 | Technically enums can be mixed with string and numeric members, but it's not clear why you would ever want to do so: 85 | 86 | ```ts 87 | enum BooleanLikeHeterogeneousEnum { 88 | No = 0, 89 | Yes = "YES", 90 | } 91 | ``` 92 | 93 | Unless you're really trying to take advantage of JavaScript's runtime behavior in a clever way, it's advised that you don't do this. 94 | 95 | ## Computed and constant members 96 | 97 | Each enum member has a value associated with it which can be either *constant* or *computed*. 98 | An enum member is considered constant if: 99 | 100 | * It is the first member in the enum and it has no initializer, in which case it's assigned the value `0`: 101 | 102 | ```ts 103 | // E.X is constant: 104 | enum E { X } 105 | ``` 106 | 107 | * It does not have an initializer and the preceding enum member was a *numeric* constant. 108 | In this case the value of the current enum member will be the value of the preceding enum member plus one. 109 | 110 | ```ts 111 | // All enum members in 'E1' and 'E2' are constant. 112 | 113 | enum E1 { X, Y, Z } 114 | 115 | enum E2 { 116 | A = 1, B, C 117 | } 118 | ``` 119 | 120 | * The enum member is initialized with a constant enum expression. 121 | A constant enum expression is a subset of TypeScript expressions that can be fully evaluated at compile time. 122 | An expression is a constant enum expression if it is: 123 | 1. a literal enum expression (basically a string literal or a numeric literal) 124 | 2. a reference to previously defined constant enum member (which can originate from a different enum). 125 | 3. a parenthesized constant enum expression 126 | 4. one of the `+`, `-`, `~` unary operators applied to constant enum expression 127 | 5. `+`, `-`, `*`, `/`, `%`, `<<`, `>>`, `>>>`, `&`, `|`, `^` binary operators with constant enum expressions as operands 128 | It is a compile time error for constant enum expressions to be evaluated to `NaN` or `Infinity`. 129 | 130 | In all other cases enum member is considered computed. 131 | 132 | ```ts 133 | enum FileAccess { 134 | // constant members 135 | None, 136 | Read = 1 << 1, 137 | Write = 1 << 2, 138 | ReadWrite = Read | Write, 139 | // computed member 140 | G = "123".length 141 | } 142 | ``` 143 | 144 | ## Union enums and enum member types 145 | 146 | There is a special subset of constant enum members that aren't calculated: literal enum members. 147 | A literal enum member is a constant enum member with no initialized value, or with values that are initialized to 148 | 149 | * any string literal (e.g. `"foo"`, `"bar`, `"baz"`) 150 | * any numeric literal (e.g. `1`, `100`) 151 | * a unary minus applied to any numeric literal (e.g. `-1`, `-100`) 152 | 153 | When all members in an enum have literal enum values, some special semantics come to play. 154 | 155 | The first is that enum members also become types as well! 156 | For example, we can say that certain members can *only* have the value of an enum member: 157 | 158 | ```ts 159 | enum ShapeKind { 160 | Circle, 161 | Square, 162 | } 163 | 164 | interface Circle { 165 | kind: ShapeKind.Circle; 166 | radius: number; 167 | } 168 | 169 | interface Square { 170 | kind: ShapeKind.Square; 171 | sideLength: number; 172 | } 173 | 174 | let c: Circle = { 175 | kind: ShapeKind.Square, 176 | // ~~~~~~~~~~~~~~~~ Error! 177 | radius: 100, 178 | } 179 | ``` 180 | 181 | The other change is that enum types themselves effectively become a *union* of each enum member. 182 | While we haven't discussed [union types](./Advanced Types.md#union-types) yet, all that you need to know is that with union enums, the type system is able to leverage the fact that it knows the exact set of values that exist in the enum itself. 183 | Because of that, TypeScript can catch silly bugs where we might be comparing values incorrectly. 184 | For example: 185 | 186 | ```ts 187 | enum E { 188 | Foo, 189 | Bar, 190 | } 191 | 192 | function f(x: E) { 193 | if (x !== E.Foo || x !== E.Bar) { 194 | // ~~~~~~~~~~~ 195 | // Error! Operator '!==' cannot be applied to types 'E.Foo' and 'E.Bar'. 196 | } 197 | } 198 | ``` 199 | 200 | In that example, we first checked whether `x` was *not* `E.Foo`. 201 | If that check succeeds, then our `||` will short-circuit, and the body of the 'if' will get run. 202 | However, if the check didn't succeed, then `x` can *only* be `E.Foo`, so it doesn't make sense to see whether it's equal to `E.Bar`. 203 | 204 | ## Enums at runtime 205 | 206 | Enums are real objects that exist at runtime. 207 | For example, the following enum 208 | 209 | ```ts 210 | enum E { 211 | X, Y, Z 212 | } 213 | ``` 214 | 215 | can actually be passed around to functions 216 | 217 | ```ts 218 | function f(obj: { X: number }) { 219 | return obj.X; 220 | } 221 | 222 | // Works, since 'E' has a property named 'X' which is a number. 223 | f(E); 224 | ``` 225 | 226 | ### Reverse mappings 227 | 228 | In addition to creating an object with property names for members, numeric enums members also get a *reverse mapping* from enum values to enum names. 229 | For example, in this example: 230 | 231 | ```ts 232 | enum Enum { 233 | A 234 | } 235 | let a = Enum.A; 236 | let nameOfA = Enum[a]; // "A" 237 | ``` 238 | 239 | TypeScript might compile this down to something like the the following JavaScript: 240 | 241 | ```js 242 | var Enum; 243 | (function (Enum) { 244 | Enum[Enum["A"] = 0] = "A"; 245 | })(Enum || (Enum = {})); 246 | var a = Enum.A; 247 | var nameOfA = Enum[a]; // "A" 248 | ``` 249 | 250 | In this generated code, an enum is compiled into an object that stores both forward (`name` -> `value`) and reverse (`value` -> `name`) mappings. 251 | References to other enum members are always emitted as property accesses and never inlined. 252 | 253 | Keep in mind that string enum members *do not* get a reverse mapping generated at all. 254 | 255 | ### `const` enums 256 | 257 | In most cases, enums are a perfectly valid solution. 258 | However sometimes requirements are tighter. 259 | To avoid paying the cost of extra generated code and additional indirection when accessing enum values, it's possible to use `const` enums. 260 | Const enums are defined using the `const` modifier on our enums: 261 | 262 | ```ts 263 | const enum Enum { 264 | A = 1, 265 | B = A * 2 266 | } 267 | ``` 268 | 269 | Const enums can only use constant enum expressions and unlike regular enums they are completely removed during compilation. 270 | Const enum members are inlined at use sites. 271 | This is possible since const enums cannot have computed members. 272 | 273 | ```ts 274 | const enum Directions { 275 | Up, 276 | Down, 277 | Left, 278 | Right 279 | } 280 | 281 | let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right] 282 | ``` 283 | 284 | in generated code will become 285 | 286 | ```js 287 | var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */]; 288 | ``` 289 | 290 | ## Ambient enums 291 | 292 | Ambient enums are used to describe the shape of already existing enum types. 293 | 294 | ```ts 295 | declare enum Enum { 296 | A = 1, 297 | B, 298 | C = 2 299 | } 300 | ``` 301 | 302 | One important difference between ambient and non-ambient enums is that, in regular enums, members that don't have an initializer will be considered constant if its preceding enum member is considered constant. 303 | In contrast, an ambient (and non-const) enum member that does not have initializer is *always* considered computed. 304 | -------------------------------------------------------------------------------- /pages/Basic Types.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | For programs to be useful, we need to be able to work with some of the simplest units of data: numbers, strings, structures, boolean values, and the like. 4 | In TypeScript, we support much the same types as you would expect in JavaScript, with a convenient enumeration type thrown in to help things along. 5 | 6 | # Boolean 7 | 8 | The most basic datatype is the simple true/false value, which JavaScript and TypeScript call a `boolean` value. 9 | 10 | ```ts 11 | let isDone: boolean = false; 12 | ``` 13 | 14 | # Number 15 | 16 | As in JavaScript, all numbers in TypeScript are floating point values. 17 | These floating point numbers get the type `number`. 18 | In addition to hexadecimal and decimal literals, TypeScript also supports binary and octal literals introduced in ECMAScript 2015. 19 | 20 | ```ts 21 | let decimal: number = 6; 22 | let hex: number = 0xf00d; 23 | let binary: number = 0b1010; 24 | let octal: number = 0o744; 25 | ``` 26 | 27 | # String 28 | 29 | Another fundamental part of creating programs in JavaScript for webpages and servers alike is working with textual data. 30 | As in other languages, we use the type `string` to refer to these textual datatypes. 31 | Just like JavaScript, TypeScript also uses double quotes (`"`) or single quotes (`'`) to surround string data. 32 | 33 | ```ts 34 | let color: string = "blue"; 35 | color = 'red'; 36 | ``` 37 | 38 | You can also use *template strings*, which can span multiple lines and have embedded expressions. 39 | These strings are surrounded by the backtick/backquote (`` ` ``) character, and embedded expressions are of the form `${ expr }`. 40 | 41 | ```ts 42 | let fullName: string = `Bob Bobbington`; 43 | let age: number = 37; 44 | let sentence: string = `Hello, my name is ${ fullName }. 45 | 46 | I'll be ${ age + 1 } years old next month.`; 47 | ``` 48 | 49 | This is equivalent to declaring `sentence` like so: 50 | 51 | ```ts 52 | let sentence: string = "Hello, my name is " + fullName + ".\n\n" + 53 | "I'll be " + (age + 1) + " years old next month."; 54 | ``` 55 | 56 | # Array 57 | 58 | TypeScript, like JavaScript, allows you to work with arrays of values. 59 | Array types can be written in one of two ways. 60 | In the first, you use the type of the elements followed by `[]` to denote an array of that element type: 61 | 62 | ```ts 63 | let list: number[] = [1, 2, 3]; 64 | ``` 65 | 66 | The second way uses a generic array type, `Array`: 67 | 68 | ```ts 69 | let list: Array = [1, 2, 3]; 70 | ``` 71 | 72 | # Tuple 73 | 74 | Tuple types allow you to express an array where the type of a fixed number of elements is known, but need not be the same. 75 | For example, you may want to represent a value as a pair of a `string` and a `number`: 76 | 77 | ```ts 78 | // Declare a tuple type 79 | let x: [string, number]; 80 | // Initialize it 81 | x = ["hello", 10]; // OK 82 | // Initialize it incorrectly 83 | x = [10, "hello"]; // Error 84 | ``` 85 | 86 | When accessing an element with a known index, the correct type is retrieved: 87 | 88 | ```ts 89 | console.log(x[0].substr(1)); // OK 90 | console.log(x[1].substr(1)); // Error, 'number' does not have 'substr' 91 | ``` 92 | 93 | When accessing an element outside the set of known indices, a union type is used instead: 94 | 95 | ```ts 96 | x[3] = "world"; // OK, 'string' can be assigned to 'string | number' 97 | 98 | console.log(x[5].toString()); // OK, 'string' and 'number' both have 'toString' 99 | 100 | x[6] = true; // Error, 'boolean' isn't 'string | number' 101 | ``` 102 | 103 | Union types are an advanced topic that we'll cover in a later chapter. 104 | 105 | # Enum 106 | 107 | A helpful addition to the standard set of datatypes from JavaScript is the `enum`. 108 | As in languages like C#, an enum is a way of giving more friendly names to sets of numeric values. 109 | 110 | ```ts 111 | enum Color {Red, Green, Blue} 112 | let c: Color = Color.Green; 113 | ``` 114 | 115 | By default, enums begin numbering their members starting at `0`. 116 | You can change this by manually setting the value of one of its members. 117 | For example, we can start the previous example at `1` instead of `0`: 118 | 119 | ```ts 120 | enum Color {Red = 1, Green, Blue} 121 | let c: Color = Color.Green; 122 | ``` 123 | 124 | Or, even manually set all the values in the enum: 125 | 126 | ```ts 127 | enum Color {Red = 1, Green = 2, Blue = 4} 128 | let c: Color = Color.Green; 129 | ``` 130 | 131 | A handy feature of enums is that you can also go from a numeric value to the name of that value in the enum. 132 | For example, if we had the value `2` but weren't sure what that mapped to in the `Color` enum above, we could look up the corresponding name: 133 | 134 | ```ts 135 | enum Color {Red = 1, Green, Blue} 136 | let colorName: string = Color[2]; 137 | 138 | alert(colorName); // Displays 'Green' as it's value is 2 above 139 | ``` 140 | 141 | # Any 142 | 143 | We may need to describe the type of variables that we do not know when we are writing an application. 144 | These values may come from dynamic content, e.g. from the user or a 3rd party library. 145 | In these cases, we want to opt-out of type-checking and let the values pass through compile-time checks. 146 | To do so, we label these with the `any` type: 147 | 148 | ```ts 149 | let notSure: any = 4; 150 | notSure = "maybe a string instead"; 151 | notSure = false; // okay, definitely a boolean 152 | ``` 153 | 154 | The `any` type is a powerful way to work with existing JavaScript, allowing you to gradually opt-in and opt-out of type-checking during compilation. 155 | You might expect `Object` to play a similar role, as it does in other languages. 156 | But variables of type `Object` only allow you to assign any value to them - you can't call arbitrary methods on them, even ones that actually exist: 157 | 158 | ```ts 159 | let notSure: any = 4; 160 | notSure.ifItExists(); // okay, ifItExists might exist at runtime 161 | notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check) 162 | 163 | let prettySure: Object = 4; 164 | prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'. 165 | ``` 166 | 167 | The `any` type is also handy if you know some part of the type, but perhaps not all of it. 168 | For example, you may have an array but the array has a mix of different types: 169 | 170 | ```ts 171 | let list: any[] = [1, true, "free"]; 172 | 173 | list[1] = 100; 174 | ``` 175 | 176 | # Void 177 | 178 | `void` is a little like the opposite of `any`: the absence of having any type at all. 179 | You may commonly see this as the return type of functions that do not return a value: 180 | 181 | ```ts 182 | function warnUser(): void { 183 | alert("This is my warning message"); 184 | } 185 | ``` 186 | 187 | Declaring variables of type `void` is not useful because you can only assign `undefined` or `null` to them: 188 | 189 | ```ts 190 | let unusable: void = undefined; 191 | ``` 192 | 193 | # Null and Undefined 194 | 195 | In TypeScript, both `undefined` and `null` actually have their own types named `undefined` and `null` respectively. 196 | Much like `void`, they're not extremely useful on their own: 197 | 198 | ```ts 199 | // Not much else we can assign to these variables! 200 | let u: undefined = undefined; 201 | let n: null = null; 202 | ``` 203 | 204 | By default `null` and `undefined` are subtypes of all other types. 205 | That means you can assign `null` and `undefined` to something like `number`. 206 | 207 | However, when using the `--strictNullChecks` flag, `null` and `undefined` are only assignable to `void` and their respective types. 208 | This helps avoid *many* common errors. 209 | In cases where you want to pass in either a `string` or `null` or `undefined`, you can use the union type `string | null | undefined`. 210 | Once again, more on union types later on. 211 | 212 | > As a note: we encourage the use of `--strictNullChecks` when possible, but for the purposes of this handbook, we will assume it is turned off. 213 | 214 | # Never 215 | 216 | The `never` type represents the type of values that never occur. 217 | For instance, `never` is the return type for a function expression or an arrow function expression that always throws an exception or one that never returns; 218 | Variables also acquire the type `never` when narrowed by any type guards that can never be true. 219 | 220 | The `never` type is a subtype of, and assignable to, every type; however, *no* type is a subtype of, or assignable to, `never` (except `never` itself). 221 | Even `any` isn't assignable to `never`. 222 | 223 | Some examples of functions returning `never`: 224 | 225 | ```ts 226 | // Function returning never must have unreachable end point 227 | function error(message: string): never { 228 | throw new Error(message); 229 | } 230 | 231 | // Inferred return type is never 232 | function fail() { 233 | return error("Something failed"); 234 | } 235 | 236 | // Function returning never must have unreachable end point 237 | function infiniteLoop(): never { 238 | while (true) { 239 | } 240 | } 241 | ``` 242 | 243 | # Type assertions 244 | 245 | Sometimes you'll end up in a situation where you'll know more about a value than TypeScript does. 246 | Usually this will happen when you know the type of some entity could be more specific than its current type. 247 | 248 | *Type assertions* are a way to tell the compiler "trust me, I know what I'm doing." 249 | A type assertion is like a type cast in other languages, but performs no special checking or restructuring of data. 250 | It has no runtime impact, and is used purely by the compiler. 251 | TypeScript assumes that you, the programmer, have performed any special checks that you need. 252 | 253 | Type assertions have two forms. 254 | One is the "angle-bracket" syntax: 255 | 256 | ```ts 257 | let someValue: any = "this is a string"; 258 | 259 | let strLength: number = (someValue).length; 260 | ``` 261 | 262 | And the other is the `as`-syntax: 263 | 264 | ```ts 265 | let someValue: any = "this is a string"; 266 | 267 | let strLength: number = (someValue as string).length; 268 | ``` 269 | 270 | The two samples are equivalent. 271 | Using one over the other is mostly a choice of preference; however, when using TypeScript with JSX, only `as`-style assertions are allowed. 272 | 273 | # A note about `let` 274 | 275 | You may've noticed that so far, we've been using the `let` keyword instead of JavaScript's `var` keyword which you might be more familiar with. 276 | The `let` keyword is actually a newer JavaScript construct that TypeScript makes available. 277 | We'll discuss the details later, but many common problems in JavaScript are alleviated by using `let`, so you should use it instead of `var` whenever possible. 278 | -------------------------------------------------------------------------------- /pages/Namespaces.md: -------------------------------------------------------------------------------- 1 | > **A note about terminology:** 2 | It's important to note that in TypeScript 1.5, the nomenclature has changed. 3 | "Internal modules" are now "namespaces". 4 | "External modules" are now simply "modules", as to align with [ECMAScript 2015](http://www.ecma-international.org/ecma-262/6.0/)'s terminology, (namely that `module X {` is equivalent to the now-preferred `namespace X {`). 5 | 6 | # Introduction 7 | 8 | This post outlines the various ways to organize your code using namespaces (previously "internal modules") in TypeScript. 9 | As we alluded in our note about terminology, "internal modules" are now referred to as "namespaces". 10 | Additionally, anywhere the `module` keyword was used when declaring an internal module, the `namespace` keyword can and should be used instead. 11 | This avoids confusing new users by overloading them with similarly named terms. 12 | 13 | # First steps 14 | 15 | Let's start with the program we'll be using as our example throughout this page. 16 | We've written a small set of simplistic string validators, as you might write to check a user's input on a form in a webpage or check the format of an externally-provided data file. 17 | 18 | ## Validators in a single file 19 | 20 | ```ts 21 | interface StringValidator { 22 | isAcceptable(s: string): boolean; 23 | } 24 | 25 | let lettersRegexp = /^[A-Za-z]+$/; 26 | let numberRegexp = /^[0-9]+$/; 27 | 28 | class LettersOnlyValidator implements StringValidator { 29 | isAcceptable(s: string) { 30 | return lettersRegexp.test(s); 31 | } 32 | } 33 | 34 | class ZipCodeValidator implements StringValidator { 35 | isAcceptable(s: string) { 36 | return s.length === 5 && numberRegexp.test(s); 37 | } 38 | } 39 | 40 | // Some samples to try 41 | let strings = ["Hello", "98052", "101"]; 42 | 43 | // Validators to use 44 | let validators: { [s: string]: StringValidator; } = {}; 45 | validators["ZIP code"] = new ZipCodeValidator(); 46 | validators["Letters only"] = new LettersOnlyValidator(); 47 | 48 | // Show whether each string passed each validator 49 | for (let s of strings) { 50 | for (let name in validators) { 51 | let isMatch = validators[name].isAcceptable(s); 52 | console.log(`'${ s }' ${ isMatch ? "matches" : "does not match" } '${ name }'.`); 53 | } 54 | } 55 | ``` 56 | 57 | # Namespacing 58 | 59 | As we add more validators, we'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. 60 | Instead of putting lots of different names into the global namespace, let's wrap up our objects into a namespace. 61 | 62 | In this example, we'll move all validator-related entities into a namespace called `Validation`. 63 | Because we want the interfaces and classes here to be visible outside the namespace, we preface them with `export`. 64 | Conversely, the variables `lettersRegexp` and `numberRegexp` are implementation details, so they are left unexported and will not be visible to code outside the namespace. 65 | In the test code at the bottom of the file, we now need to qualify the names of the types when used outside the namespace, e.g. `Validation.LettersOnlyValidator`. 66 | 67 | ## Namespaced Validators 68 | 69 | ```ts 70 | namespace Validation { 71 | export interface StringValidator { 72 | isAcceptable(s: string): boolean; 73 | } 74 | 75 | const lettersRegexp = /^[A-Za-z]+$/; 76 | const numberRegexp = /^[0-9]+$/; 77 | 78 | export class LettersOnlyValidator implements StringValidator { 79 | isAcceptable(s: string) { 80 | return lettersRegexp.test(s); 81 | } 82 | } 83 | 84 | export class ZipCodeValidator implements StringValidator { 85 | isAcceptable(s: string) { 86 | return s.length === 5 && numberRegexp.test(s); 87 | } 88 | } 89 | } 90 | 91 | // Some samples to try 92 | let strings = ["Hello", "98052", "101"]; 93 | 94 | // Validators to use 95 | let validators: { [s: string]: Validation.StringValidator; } = {}; 96 | validators["ZIP code"] = new Validation.ZipCodeValidator(); 97 | validators["Letters only"] = new Validation.LettersOnlyValidator(); 98 | 99 | // Show whether each string passed each validator 100 | for (let s of strings) { 101 | for (let name in validators) { 102 | console.log(`"${ s }" - ${ validators[name].isAcceptable(s) ? "matches" : "does not match" } ${ name }`); 103 | } 104 | } 105 | ``` 106 | 107 | # Splitting Across Files 108 | 109 | As our application grows, we'll want to split the code across multiple files to make it easier to maintain. 110 | 111 | ## Multi-file namespaces 112 | 113 | Here, we'll split our `Validation` namespace across many files. 114 | Even though the files are separate, they can each contribute to the same namespace and can be consumed as if they were all defined in one place. 115 | Because there are dependencies between files, we'll add reference tags to tell the compiler about the relationships between the files. 116 | Our test code is otherwise unchanged. 117 | 118 | ##### Validation.ts 119 | 120 | ```ts 121 | namespace Validation { 122 | export interface StringValidator { 123 | isAcceptable(s: string): boolean; 124 | } 125 | } 126 | ``` 127 | 128 | ##### LettersOnlyValidator.ts 129 | 130 | ```ts 131 | /// 132 | namespace Validation { 133 | const lettersRegexp = /^[A-Za-z]+$/; 134 | export class LettersOnlyValidator implements StringValidator { 135 | isAcceptable(s: string) { 136 | return lettersRegexp.test(s); 137 | } 138 | } 139 | } 140 | ``` 141 | 142 | ##### ZipCodeValidator.ts 143 | 144 | ```ts 145 | /// 146 | namespace Validation { 147 | const numberRegexp = /^[0-9]+$/; 148 | export class ZipCodeValidator implements StringValidator { 149 | isAcceptable(s: string) { 150 | return s.length === 5 && numberRegexp.test(s); 151 | } 152 | } 153 | } 154 | ``` 155 | 156 | ##### Test.ts 157 | 158 | ```ts 159 | /// 160 | /// 161 | /// 162 | 163 | // Some samples to try 164 | let strings = ["Hello", "98052", "101"]; 165 | 166 | // Validators to use 167 | let validators: { [s: string]: Validation.StringValidator; } = {}; 168 | validators["ZIP code"] = new Validation.ZipCodeValidator(); 169 | validators["Letters only"] = new Validation.LettersOnlyValidator(); 170 | 171 | // Show whether each string passed each validator 172 | for (let s of strings) { 173 | for (let name in validators) { 174 | console.log(""" + s + "" " + (validators[name].isAcceptable(s) ? " matches " : " does not match ") + name); 175 | } 176 | } 177 | ``` 178 | 179 | Once there are multiple files involved, we'll need to make sure all of the compiled code gets loaded. 180 | There are two ways of doing this. 181 | 182 | First, we can use concatenated output using the `--outFile` flag to compile all of the input files into a single JavaScript output file: 183 | 184 | ```Shell 185 | tsc --outFile sample.js Test.ts 186 | ``` 187 | 188 | The compiler will automatically order the output file based on the reference tags present in the files. You can also specify each file individually: 189 | 190 | ```Shell 191 | tsc --outFile sample.js Validation.ts LettersOnlyValidator.ts ZipCodeValidator.ts Test.ts 192 | ``` 193 | 194 | Alternatively, we can use per-file compilation (the default) to emit one JavaScript file for each input file. 195 | If multiple JS files get produced, we'll need to use `