Typecheck/Compile JS


    // --- PROPERTIES ARE INFERRED FROM ASSIGNMENTS IN CLASS BODIES
    // just like object literals, no means for declaring properties on classes.
    // type of properties is the type given in the constructor,
    // unless its not defined there, or the type in the constructor is undefined or null
    // in that case, type 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,
    // defined just in methods, getters, or setters are considered optional
    class C {
      constructor() {
        this.constructorOnly = 0
        this.constructorUnknown = undefined
      }
      method() {
        this.constructorOnly = false // error, constructorOnly is a number
        this.constructorUnknown = "plunkbat" // ok, constructorUnknown is string | undefined
        this.methodOnly = 'ok'  // ok, but y could also be undefined
      }
      method2() {
        this.methodOnly = true  // also, ok, y's type is string | boolean | undefined
      }
    }
    // if properties are never set in the class body, they are considered unknown
    // properties that are only read from, dd and then annotate with JSDoc
    // dont even have to give a value if it will be initialised later
    class C {
      constructor() {
        /** @type {number | undefined} */
        this.prop = undefined;
        /** @type {number | undefined} */
        this.count;
      }
    }
    let c = new C();
    c.prop = 0;          // OK
    c.count = "string";  // Error: string is not assignable to number|undefined

    // --- CONSTRUCTOR FUNCTIONS ARE EQUIVALENT TO CLASSES
    // property inference rules described above work exactly the same way
    function C() {
      this.constructorOnly = 0
      this.constructorUnknown = undefined
    }
    C.prototype.method = function() {
      this.constructorOnly = false // error
      this.constructorUnknown = "plunkbat" // OK, the type is string | undefined
    }

    // --- CommonJS MODULES ARE SUPPORTED, TS understand them in .js files
    // assignments to "exports" and "module.exports" are recognized as export declarations
    // "require" function calls are recognized as module imports. For example
    // same as - import module "fs":
    const fs = require("fs");
    // same as - export function readFile:
    module.exports.readFile = function(f) { return fs.readFileSync(f); }

    // --- CLASSES, FUNCTIONS, AND OBJECT LITERALS ARE NAMESPACES
    class C { } // class
    C.D = class { }
    function Outer() { this.y = 2 } // function
    Outer.Inner = function() { this.yy = 2 }
    var ns = {} // object
    ns.C = class { }
    ns.func = function() { }
    var ns = (function (n) { // IIFE
      return n || {};
    })();
    ns.CONST = 1
    var assign = assign || function() { /* code */ } // defaulting to global
    assign.extra = 1

    // --- OBJECT LITERALS ARE OPEN-ENDED
    // for .ts files an object literal that initializes a variable declaration
    // gives its type to the declaration, no new members can be added
    // that were not specified in the original literal.
    // this rule is relaxed in a .js, object literals have an open-ended type
    // behave as if they have an index signature "[x:string]: any"
    var obj = { a: 1 };
    obj.b = 2;  // Allowed
    // behavior can be changed by specifying a JSDoc type for the variable
    /** @type {{a: number}} */
    var obj = { a: 1 };
    obj.b = 2;  // Error, type {a: number} does not have property b

    // --- NULL, UNDEFINED, EMPTY ARRAY INITIALIZERS ARE OF TYPE any OR any[]
    // any variable/parameter/property initialized with null/undefined will have type any
    // even if strict null checks is turned on
    // only exception is for properties that have multiple initializers as described above
    function Foo(i = null) {
      if (!i) i = 1;
      var j = undefined;
      j = 2;
      this.l = [];
    }
    var foo = new Foo();
    foo.l.push(foo.i);
    foo.l.push("end");

    // --- FUNCTION PARAMETERS ARE OPTIONAL BY DEFAULT
    // calls with fewer arguments than the declared number of parameters are allowed
    // it is an error to call a function with too many arguments
    function bar(a, b) { console.log(a + " " + b); }
    bar(1);       // OK, second argument considered optional
    bar(1, 2);
    bar(1, 2, 3); // Error, too many arguments
    // JSDoc annotated functions are excluded from this rule, use optional parameter syntax
    /**
    * @param {string} [somebody] - Somebody's name.
    */
    function sayHello(somebody) {
      if (!somebody) { somebody = 'John Doe'; }
      console.log('Hello ' + somebody);
    }
    sayHello();

    // --- VAR-ARGS PARAMETER DECLARATION INFERRED FROM USE OF arguments
    // function whose body has a reference to the arguments reference is implicitly
    // considered to have a var-arg parameter (i.e. (...arg: any[]) => any)
    /** @param {...number} args */
    function sum(/* numbers */) {
      var total = 0
      for (var i = 0; i < arguments.length; i++) {
        total += arguments[i]
      }
      return total
    }

    // --- UNSPECIFIED TYPE PARAMETERS DEFAULT TO any
    // since there is no natural syntax for specifying generic type parameters in JS
    import { Component } from "react";
    /**
      * @augments {Component<{a: number}, State>}
      */
    class MyComponent extends Component {
      render() {
        this.props.b; // Error: b does not exist on {a:number}
        // this.props.b; // would be allowed without JSDoc, since this.props is of type any
      }
    }
    // unspecified type argument in JSDoc defaults to any
    /** @type{Array} */
    var x = [];
    x.push(1);        // OK
    x.push("string"); // OK, x is of type Array<any>
    /** @type{Array.<number>} */
    var y = [];
    y.push(1);        // OK
    y.push("string"); // Error, string is not assignable to number
  

migrating from JS


    /*
      projectRoot
      ├── src
      │   ├── file1.js
      │   └── file2.js
      ├── built
      └── tsconfig.json
    */
    // tsconfig.json
    {
      "compilerOptions": {
        "outDir": "./built", // emit all of the output files in built
        "allowJs": true, // accept JavaScript files as inputs
        "target": "es5" // translate newer JS constructs down to an older version like ES5
        // noImplicitReturns - prevents from forgetting to return at the end of a function
        // noFallthroughCasesInSwitch - to not forget a break statement between cases in a switch block
        // allowUnreachableCode|allowUnusedLabels - warn about unreachable code and labels
      },
      "include": [
        "./src/**/*" // read any files it understands in the src directory, repeating structure
      ]
    }
    // use "tsc" to compile

    // if you see errors for a module, try find its declaration files:
    // npm install -S @types/lodash

    // Importing from Modules
    import foo = require("foo");
    foo.doStuff();
    // Exporting from Modules
    function foo() { /*...*/ }
    export = foo;
    // Sequentially Added Properties
    let options = {
      color: "red",
      volume: 11
    };
    interface Options { color: string; volume: number }
    let options = {} as Options;
    options.color = "red";
    options.volume = 11;
  

Supported JSDoc

@type


    // reference a type name, use any TS type, and most JSDoc types
    /** @type {string} */
    var s;
    /** @type {Window} */
    var win;
    /** @type {PromiseLike<string>} */
    var promisedString;
    // you can specify an HTML Element with DOM properties
    /** @type {HTMLElement} */
    var myElement = document.querySelector(selector);
    element.dataset.myData = '';
    // --- UNION, parentheses are optional for union types
    /** @type {(string | boolean)} */
    var sb;
    /** @type {string | boolean} */
    var sb;
    // --- ARRAY
    /** @type {number[]} */
    var ns;
    /** @type {Array.<number>} */
    var nds;
    /** @type {Array<number>} */
    var nas;
    // --- OBJECT LITERAL TYPES
    /** @type {{ a: string, b: number }} */
    var var9;
    // --- MAP-LIKE and ARRAY-LIKE OBJECTS using string and number index signatures
    // using either standard JSDoc syntax or TS syntax.
    // equivalence to the TS types {[x:string]:number} and {[x:number]:any},
    // map-like object that maps arbitrary "string" properties to "number"s:
    /** @type {Object.<string, number>} */
    var stringToNumber;
    /** @type {Object.<number, object>} */
    var arrayLike;
    // --- FUNCTION types using either TS or Closure syntax:
    /** @type {function(string, boolean): number} Closure syntax */
    var sbn;
    /** @type {(s: string, b: boolean) => number} TS syntax */
    var sbn2;
    /** @type {Function} */
    var fn7;
    /** @type {function} */
    var fn6;
    // --- other types from Closure also work:
    /** @type {*} - can be 'any' type */
    var star;
    /** @type {?} - unknown type (same as 'any') */
    var question;
    // cast types to other types, add @type tag before any parenthesized expression:
    /** @type {number | string} */
    var numberOrString = Math.random() < 0.5 ? "hello" : 100;
    var typeAssertedNumber = /** @type {number} */ (numberOrString)
    // --- IMPORT TYPES
    /** @param p { import("./a").Pet } */
    function walk(p) { console.log(`Walking ${p.name}...`); }
    // used in type alias declarations:
    /** @typedef Pet { import("./a").Pet } */
    /** @type {Pet} */
    var myPet;
    myPet.name;
    // used to get the type of a value from a module:
    /** @type {typeof import("./a").x } */
    var x = require("./a").x;
  

@param and @returns


    // uses the same type syntax as @type, but adds a parameter name
    // parameter may also be declared optional by surrounding the name with square brackets
    // in a variety of syntactic forms
    /**
      * @param {string}  p1 - A string param.
      * @param {string=} p2 - An optional param (Closure syntax)
      * @param {string} [p3] - Another optional param (JSDoc syntax).
      * @param {string} [p4="test"] - An optional param with a default value
      * @return {string} This is the result
      */
    function stringsStringStrings(p1, p2, p3, p4){ /*...*/}
    // return type of a function
    /** @return {PromiseLike<string>} */
    function ps(){}
    /**
    * @returns {{ a: string, b: number }} - May use '@returns' as well as '@return'
    */
    function ab(){}
  

@typedef, @callback, and @param


    // --- @typedef may be used to define complex types, similar syntax works with @param
    /**
    * @typedef {Object} SpecialType - creates a new type named 'SpecialType'
    * @property {string} prop1 - a string property of SpecialType
    * @property {number} prop2 - a number property of SpecialType
    * @property {number=} prop3 - an optional number property of SpecialType
    * @prop {number} [prop4] - an optional number property of SpecialType
    * @prop {number} [prop5=42] - an optional number property of SpecialType with default
    */
    /** @type {SpecialType} */
    var specialTypeObject;
    // you can use either object or Object on the first line
    /**
    * @typedef {object} SpecialType1 - creates a new type named 'SpecialType'
    * @property {string} prop1 - a string property of SpecialType
    * @property {number} prop2 - a number property of SpecialType
    * @property {number=} prop3 - an optional number property of SpecialType
    */
    /** @type {SpecialType1} */
    var specialTypeObject1;
    // --- @param allows a similar syntax for one-off type specifications
    // nested property names must be prefixed with the name of the parameter
    /**
    * @param {Object} options - The shape is the same as SpecialType above
    * @param {string} options.prop1
    * @param {number} options.prop2
    * @param {number=} options.prop3
    * @param {number} [options.prop4]
    * @param {number} [options.prop5=42]
    */
    function special(options) {
      return (options.prop4 || 1001) + options.prop5;
    }
    // --- @callback is similar to @typedef
    // but specifies a function type instead of an object type:
    /**
    * @callback Predicate
    * @param {string} data
    * @param {number} [index]
    * @returns {boolean}
    */
    /** @type {Predicate} */
    const ok = s => !(s.length % 2);
    // using TS syntax in a single-line @typedef
    /** @typedef {{ prop1: string, prop2: string, prop3?: number }} SpecialType */
    /** @typedef {(data: string, index?: number) => boolean} Predicate */
  

@template


    // declare generic types
    /**
    * @template T
    * @param {T} p1 - A generic parameter that flows through to the return type
    * @return {T}
    */
    function id(x){ return x }
    // use comma or multiple tags to declare multiple type parameters
    /**
    * @template T,U,V
    * @template W,X
    */
    // specify a type constraint before the type parameter name
    // only the first type parameter in a list is constrained
    /**
    * @template {string} K - K must be a string or string literal
    * @template {{ serious(): string }} Seriousalizable - must have a serious method
    * @param {K} key
    * @param {Seriousalizable} object
    */
    function seriousalize(key, object) { /*...*/ }
  

@constructor


    // make checking stricter and suggestions better
    /**
    * @constructor
    * @param {number} data
    */
    function C(data) {
      this.size = 0;
      this.initialize(data); // Should error, initializer expects a string
    }
    /**
    * @param {string} s
    */
    C.prototype.initialize = function (s) {
      this.size = s.length
    }
    var c = new C(0);
    var result = C(1); // C should only be called with new
  

@this


    // explicitly specify the type of "this", when compiler is unable
    /**
    * @this {HTMLElement}
    * @param {*} e
    */
    function callbackForLater(e) {
      this.clientHeight = parseInt(e) // should be fine!
    }
  

@extends


    // specify what the type parameter should be
    // when JS classes extend a generic base class
    // only works with classes
    /**
    * @template T
    * @extends {Set<T>}
    */
    class SortableSet extends Set { /*...*/ }
  

@enum


    // create an object literal whose members are all of a specified type
    // does not allow other members, unlike most JS object literals
    /** @enum {number} */
    const JSDocState = {
      BeginningOfLine: 0,
      SawAsterisk: 1,
      SavingComments: 2,
    }
    // can have any type, unlike TS
    /** @enum {function(number): number} */
    const Math = {
      add1: n => n + 1,
      id: n => -n,
      sub1: n => n - 1,
    }
  

more examples


    var someObj = {
      /**
      * @param {string} param1 - Docs on property assignments work
      */
      x: function(param1){}
    };
    /**
    * As do docs on variable assignments
    * @return {Window}
    */
    let someFunc = function(){};
    /**
    * And class methods
    * @param {string} greeting The greeting to use
    */
    Foo.prototype.sayHi = (greeting) => console.log("Hi!");
    /**
    * And arrow functions expressions
    * @param {number} x - A multiplier
    */
    let myArrow = x => x * x;
    /**
    * Which means it works for stateless function components in JSX too
    * @param {{a: string, b: number}} test - Some param
    */
    var sfc = (test) => <div>{test.a.charAt(0)}<div>;
    /**
    * A parameter can be a class constructor, using Closure syntax.
    *
    * @param {{new(...args: any[]): object}} C - The class to register
    */
    function registerClass(C) {}
    /**
    * @param {...string} p1 - A 'rest' arg (array) of strings. (treated as 'any')
    */
    function fn10(p1){}
    /**
    * @param {...string} p1 - A 'rest' arg (array) of strings. (treated as 'any')
    */
    function fn9(p1) { return p1.join(); }
  

patterns that are known NOT to be supported


    // referring to objects in the value space as types doesnt work
    // unless the object also creates a type, like a constructor function
    function aNormalFunction() { }
    /** @type {aNormalFunction} */
    var wrong;
    /**
    * Use 'typeof' instead:
    * @type {typeof aNormalFunction}
    */
    var right;
    // postfix equals on a property type in an object literal type
    // doesnt specify an optional property
    /** @type {{ a: string, b: number= }} */
    var wrong;
    /**
    * Use postfix question on the property name instead:
    * @type {{ a: string, b?: number }}
    */
    var right;
    // nullable types only have meaning if strictNullChecks is on:
    /**
    * @type {?number}
    * With strictNullChecks: true -- number | null
    * With strictNullChecks: off  -- number
    */
    var nullable;
    // non-nullable types have no meaning and are treated just as their original type:
    /**
    * @type {!number}
    * Just has type number
    */
    var normal;
    // unlike JSDoc type system, TS only allows you to mark types as containing null or not
    // here is no explicit non-nullability -
    // if strictNullChecks is on, then number is not nullable, if off, then number is nullable
  

Declaration File


    // --- GLOBAL LIBRARIES
    function createGreeting(s) { return "Hello, " + s; }
    // or like this:
    window.createGreeting = function(s) { return "Hello, " + s; }

    // --- MODULAR LIBRARIES
    var fs = require("fs"); // nodejs
    import fs = require("fs"); // TS, ES6
    // they typicallyincludes one of these lines in their documentation
    var someLib = require('someLib');
    // or
    define(..., ['someLib'], function(someLib) { /*...*/ });

    // --- UMD
    import moment = require("moment"); // as a module
    console.log(moment.format());
    // vanilla browser environment version
    console.log(moment.format());
    // templates available for modules:
    // 1 - use module-function.d.ts if your module can be called like a function:
    var x = require("foo");
    var y = x(42); // calling 'x' as a function
    // 2 - use module-class.d.ts if your module can be constructed using new:
    var x = require("bar");
    var y = new x("hello"); // using 'new' operator on the imported variable
    // 3 - use the module.d.ts - if your module is not callable or constructable
  

CONSUMPTION DECLARATION


    // add a declaration file for a popular npm module
    npm install --save-dev @types/module
    // for example:
    npm install --save lodash
    npm install --save-dev @types/lodash
    // npm will create node_modules/@types with subdirectories for each module with an index.d.ts file
    // file doesnt contain any code, only describes the module interface, such as classes and types
    // you still need to import the actual module:
    import * as _ from "lodash";
    _.padStart("Hello TS!", 20, " ");
    // or if you are not using modules, you can just use the global variable (_)
    _.padStart("Hello TS!", 20, " ");

    // type declaration packages should always have the same name as the package name on npm
    // but prefixed with @types/
    // check out https://aka.ms/types to find the package for your favorite library
  

WRITING DECLARATIONS EXAMPLES


    // --- GLOBAL VARIABLES
    // use declare var to declare variables
    // if the variable is read-only, you can use declare const
    // use declare let if the variable is block-scoped
    // DOCS: global variable foo contains the number of widgets present
    declare var foo: number; // number of widgets present
    //
    console.log("Half the number of widgets is " + (foo / 2));

    // --- GLOBAL FUNCTIONS
    // DOCS: call the function greet with a string to show a greeting to the user
    declare function greet(greeting: string): void;
    //
    greet("hello, world");

    // --- OBJECTS WITH PROPERTIES
    // use declare namespace to describe types or values accessed by dotted notation
    // DOCS: global variable myLib has a function makeGreeting for creating greetings,
    // and a property numberOfGreetings indicating the number of greetings made so far
    declare namespace myLib {
      function makeGreeting(s: string): string;
      let numberOfGreetings: number;
    }
    //
    let result = myLib.makeGreeting("hello, world");
    console.log("The computed greeting is:" + result);
    let count = myLib.numberOfGreetings;

    // --- OVERLOADED FUNCTIONS
    // DOCS: getWidget function accepts a number and returns a Widget,
    // or accepts a string and returns a Widget array
    let x: Widget = getWidget(43);
    let arr: Widget[] = getWidget("all of them");
    //
    declare function getWidget(n: number): Widget;
    declare function getWidget(s: string): Widget[];

    // --- REUSABLE TYPES (INTERFACES)
    // DOCS: when specifying a greeting, you must pass a GreetingSettings object,
    // this object has the following properties:
    // 1 - greeting: Mandatory string
    // 2 - duration: Optional length of time (in milliseconds)
    // 3 - color: Optional string, e.g. "#ff00ff"
    interface GreetingSettings {
      greeting: string;
      duration?: number;
      color?: string;
    }
    declare function greet(setting: GreetingSettings): void;
    //
    greet({
      greeting: "hello world",
      duration: 4000
    });

    // --- REUSABLE TYPES (TYPE ALIASES)
    // DOCS: nywhere a greeting is expected, you can provide a string,
    // a function returning a string, or a Greeter instance
    // type GreetingLike = string | (() => string) | MyGreeter;
    // declare function greet(g: GreetingLike): void;
    //
    function getGreeting() { return "howdy"; }
    class MyGreeter extends Greeter { }
    greet("hello");
    greet(getGreeting);
    greet(new MyGreeter());

    // --- ORGANIZING TYPES, use namespace
    // DOCS: greeter object can log to a file or display an alert
    // you can provide LogOptions to .log(...) and alert options to .alert(...)
    declare namespace GreetingLib {
      interface LogOptions {
          verbose?: boolean;
      }
      interface AlertOptions {
        modal: boolean;
        title?: string;
        color?: string;
      }
    }
    //
    const g = new Greeter("Hello");
    g.log({ verbose: true });
    g.alert({ modal: false, title: "Current Greeting" });
    // nested namespaces in one declaration:
    declare namespace GreetingLib.Options {
      // Refer to via GreetingLib.Options.Log
      interface Log {
        verbose?: boolean;
      }
      interface Alert {
        modal: boolean;
        title?: string;
        color?: string;
      }
    }

    // --- CLASSES
    // DOCS: you can create a greeter by instantiating the Greeter object,
    // or create a customized greeter by extending from it
    declare class Greeter {
      constructor(greeting: string);
      greeting: string;
      showGreeting(): void;
    }
    //
    const myGreeter = new Greeter("hello, world");
    myGreeter.greeting = "howdy";
    myGreeter.showGreeting();
    class SpecialGreeter extends Greeter {
      constructor() {
        super("Very special greetings");
      }
    }
  

COMPLEX DEFINITION FILES


    // --- CREATING TYPES
    // type alias declaration (type sn = number | string;)
    // interface declaration (interface I { x: number[]; })
    // class declaration (class C { })
    // enum declaration (enum E { A, B, C })
    // import declaration which refers to a type
    // --- CREATE VALUE
    // let, const, and var declarations
    // namespace or module declaration which contains a value
    // enum declaration
    // class declaration
    // import declaration which refers to a value
    // function declaration

    // types can exist in namespaces

    // simple Combinations: one name, multiple meanings
    let m: A.A = A;
    // A is used first as a namespace, then as a type name, then as a value
    // these meanings might end up referring to entirely different declarations!

    // module file foo.d.ts
    export var SomeVar: { a: SomeType };
    export interface SomeType { count: number; }
    // consumed it:
    import * as foo from './foo';
    let x: foo.SomeType = foo.SomeVar.a;
    console.log(x.count);

    // use COMBINING to present two different objects
    // (the value and the type) under the same name Bar
    export var Bar: { a: Bar };
    export interface Bar { count: number; }
    // consuming code:
    import { Bar } from './foo';
    let x: Bar = Bar.a;
    console.log(x.count);
    // we didnt have to declare the Bar value as being of the Bar type - theyre independent

    // some kinds of declarations can be combined across multiple declarations
    // class C { } and interface C { } can co-exist
    // and both contribute properties to the C types.
    // legal as does not create a conflict

    // ADD ADDITIONAL MEMBERS TO AN INTERFACE with another interface declaration:
    interface Foo { x: number; }
    // ... elsewhere ...
    interface Foo { y: number; }
    let a: Foo = ...;
    console.log(a.x + a.y); // OK
    // with classes:
    class Foo { x: number; }
    // ... elsewhere ...
    interface Foo { y: number; }
    let a: Foo = ...;
    console.log(a.x + a.y); // OK

    // NAMESPACE DECLARATION can be used to add new types, values, and namespaces
    // add a static member to a class:
    class C { }
    // ... elsewhere ...
    namespace C { export let x: number; }
    let y = C.x; // OK
    // add a namespaced type to a class:
    class C { }
    // ... elsewhere ...
    namespace C { export interface D { } }
    let y: C.D; // OK

    // PERFORM MANY DIFFERENT MERGES USING NAMESPACE DECLARATIONS:
    // value X (because the namespace declaration contains a value, Z);
    // namespace X (because the namespace declaration contains a type, Y);
    namespace X {
      // type Y in the X namespace;
      export interface Y { }
      // type Z in the X namespace (the instance shape of the class);
      // value Z - a property of the X value (the constructor function of the class);
      export class Z { }
    }
    // ... elsewhere ...
    namespace X {
      // value Y (of type number) that is a property of the X value;
      export var Y: number;
      // namespace Z;
      // value Z that is a property of the X value;
      export namespace Z {
        // type C in the X.Z namespace;
        // value C that is a property of the X.Z value;
        export class C { }
      }
    }
    // type X;
    type X = string;
  

TEMPLATE - module.d.ts


    // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
    // Project: [~THE PROJECT NAME~]
    // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>

    /* This is the module template file. You should rename it to index.d.ts
      * and place it in a folder with the same name as the module.
      * For example, if you were writing a file for "super-greeter", this
      * file should be 'super-greeter/index.d.ts'
      */

    /* If this module is a UMD module that exposes a global variable 'myLib' when
      * loaded outside a module loader environment, declare that global here.
      * Otherwise, delete this declaration.
      */
    export as namespace myLib;

    /* If this module has methods, declare them as functions like so.
      */
    export function myMethod(a: string): string;
    export function myOtherMethod(a: number): number;

    /* You can declare types that are available via importing the module */
    export interface someType {
        name: string;
        length: number;
        extras?: string[];
    }

    /* You can declare properties of the module using const, let, or var */
    export const myField: number;

    /* If there are types, properties, or methods inside dotted names
      * of the module, declare them inside a 'namespace'.
      */
    export namespace subProp {
        /* For example, given this definition, someone could write:
          *   import { subProp } from 'yourModule';
          *   subProp.foo();
          * or
          *   import * as yourMod from 'yourModule';
          *   yourMod.subProp.foo();
          */
        export function foo(): void;
    }
  

TEMPLATE - module-plugin.d.ts


    // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
    // Project: [~THE PROJECT NAME~]
    // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>

    /* This is the module plugin template file. You should rename it to index.d.ts
      * and place it in a folder with the same name as the module.
      * For example, if you were writing a file for "super-greeter", this
      * file should be 'super-greeter/index.d.ts'
      */

    /* On this line, import the module which this module adds to */
    import * as m from 'someModule';

    /* You can also import other modules if needed */
    import * as other from 'anotherModule';

    /* Here, declare the same module as the one you imported above */
    declare module 'someModule' {
        /* Inside, add new function, classes, or variables. You can use
          * unexported types from the original module if needed. */
        export function theNewMethod(x: m.foo): other.bar;

        /* You can also add new properties to existing interfaces from
          * the original module by writing interface augmentations */
        export interface SomeModuleOptions {
            someModuleSetting?: string;
        }

        /* New types can also be declared and will appear as if they
          * are in the original module */
        export interface MyModulePluginOptions {
            size: number;
        }
    }
  

TEMPLATE - module-function.d.ts


    // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
    // Project: [~THE PROJECT NAME~]
    // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>

    /* This is the module template file for function modules.
      * You should rename it to index.d.ts and place it in a folder with the same name as the module.
      * For example, if you were writing a file for "super-greeter", this
      * file should be 'super-greeter/index.d.ts'
      */

    /* Note that ES6 modules cannot directly export callable functions.
      * This file should be imported using the CommonJS-style:
      *   import x = require('someLibrary');
      *
      * Refer to the documentation to understand common
      * workarounds for this limitation of ES6 modules.
      */

    /* If this module is a UMD module that exposes a global variable 'myFuncLib' when
      * loaded outside a module loader environment, declare that global here.
      * Otherwise, delete this declaration.
      */
    export as namespace myFuncLib;

    /* This declaration specifies that the function
      * is the exported object from the file
      */
    export = MyFunction;

    /* This example shows how to have multiple overloads for your function */
    declare function MyFunction(name: string): MyFunction.NamedReturnType;
    declare function MyFunction(length: number): MyFunction.LengthReturnType;

    /* If you want to expose types from your module as well, you can
      * place them in this block. Often you will want to describe the
      * shape of the return type of the function; that type should
      * be declared in here, as this example shows.
      */
    declare namespace MyFunction {
        export interface LengthReturnType {
            width: number;
            height: number;
        }
        export interface NamedReturnType {
            firstName: string;
            lastName: string;
        }

        /* If the module also has properties, declare them here. For example,
          * this declaration says that this code is legal:
          *   import f = require('myFuncLibrary');
          *   console.log(f.defaultName);
          */
        export const defaultName: string;
        export let defaultLength: number;
    }
  

TEMPLATE - module-class.d.ts


    // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
    // Project: [~THE PROJECT NAME~]
    // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>

    /* This is the module template file for class modules.
      * You should rename it to index.d.ts and place it in a folder with the same name as the module.
      * For example, if you were writing a file for "super-greeter", this
      * file should be 'super-greeter/index.d.ts'
      */

    /* Note that ES6 modules cannot directly export class objects.
      * This file should be imported using the CommonJS-style:
      *   import x = require('someLibrary');
      *
      * Refer to the documentation to understand common
      * workarounds for this limitation of ES6 modules.
      */

    /* If this module is a UMD module that exposes a global variable 'myClassLib' when
      * loaded outside a module loader environment, declare that global here.
      * Otherwise, delete this declaration.
      */
    export as namespace myClassLib;

    /* This declaration specifies that the class constructor function
      * is the exported object from the file
      */
    export = MyClass;

    /* Write your module's methods and properties in this class */
    declare class MyClass {
        constructor(someParam?: string);

        someProperty: string[];

        myMethod(opts: MyClass.MyClassMethodOptions): number;
    }

    /* If you want to expose types from your module as well, you can
      * place them in this block.
      */
    declare namespace MyClass {
        export interface MyClassMethodOptions {
            width?: number;
            height?: number;
        }
    }
  

TEMPLATE - global.d.ts


    // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
    // Project: [~THE PROJECT NAME~]
    // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>

    /* If this library is callable (e.g. can be invoked as myLib(3)),
      * include those call signatures here.
      * Otherwise, delete this section.
      */
    declare function myLib(a: string): string;
    declare function myLib(a: number): number;

    /* If you want the name of this library to be a valid type name,
      * you can do so here.
      *
      * For example, this allows us to write 'var x: myLib';
      * Be sure this actually makes sense! If it doesn't, just
      * delete this declaration and add types inside the namespace below.
      */
    interface myLib {
        name: string;
        length: number;
        extras?: string[];
    }

    /* If your library has properties exposed on a global variable,
      * place them here.
      * You should also place types (interfaces and type alias) here.
      */
    declare namespace myLib {
        //~ We can write 'myLib.timeout = 50;'
        let timeout: number;

        //~ We can access 'myLib.version', but not change it
        const version: string;

        //~ There's some class we can create via 'let c = new myLib.Cat(42)'
        //~ Or reference e.g. 'function f(c: myLib.Cat) { ... }
        class Cat {
            constructor(n: number);

            //~ We can read 'c.age' from a 'Cat' instance
            readonly age: number;

            //~ We can invoke 'c.purr()' from a 'Cat' instance
            purr(): void;
        }

        //~ We can declare a variable as
        //~   'var s: myLib.CatSettings = { weight: 5, name: "Maru" };'
        interface CatSettings {
            weight: number;
            name: string;
            tailLength?: number;
        }

        //~ We can write 'const v: myLib.VetID = 42;'
        //~  or 'const v: myLib.VetID = "bob";'
        type VetID = string | number;

        //~ We can invoke 'myLib.checkCat(c)' or 'myLib.checkCat(c, v);'
        function checkCat(c: Cat, s?: VetID);
    }
  

TEMPLATE - global-plugin.d.ts


    // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
    // Project: [~THE PROJECT NAME~]
    // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>

    /* This template shows how to write a global plugin. */

    /* Write a declaration for the original type and add new members.
      * For example, this adds a 'toBinaryString' method with to overloads to
      * the built-in number type.
      */
    interface Number {
        toBinaryString(opts?: MyLibrary.BinaryFormatOptions): string;
        toBinaryString(callback: MyLibrary.BinaryFormatCallback, opts?: MyLibrary.BinaryFormatOptions): string;
    }

    /* If you need to declare several types, place them inside a namespace
      * to avoid adding too many things to the global namespace.
      */
    declare namespace MyLibrary {
        type BinaryFormatCallback = (n: number) => string;
        interface BinaryFormatOptions {
            prefix?: string;
            padding: number;
        }
    }
  

TEMPLATE - global-modifying-module.d.ts


    // Type definitions for [~THE LIBRARY NAME~] [~OPTIONAL VERSION NUMBER~]
    // Project: [~THE PROJECT NAME~]
    // Definitions by: [~YOUR NAME~] <[~A URL FOR YOU~]>

    /* This is the global-modifying module template file. You should rename it to index.d.ts
      * and place it in a folder with the same name as the module.
      * For example, if you were writing a file for "super-greeter", this
      * file should be 'super-greeter/index.d.ts'
      */

    /* Note: If your global-modifying module is callable or constructable, you'll
      * need to combine the patterns here with those in the module-class or module-function
      * template files
      */
    declare global {
        /* Here, declare things that go in the global namespace, or augment
          * existing declarations in the global namespace
          */
        interface String {
            fancyFormat(opts: StringFormatOptions): string;
        }
    }

    /* If your module exports types or values, write them as usual */
    export interface StringFormatOptions {
        fancinessLevel: number;
    }

    /* For example, declaring a method on the module (in addition to its global side effects) */
    export function doSomething(): void;

    /* If your module exports nothing, you'll need this line. Otherwise, delete it */
    export { };
  

tsconfig.json

tsconfig.json: using the "files" property


    {
      "compilerOptions": {
        "module": "commonjs",
        "noImplicitAny": true,
        "removeComments": true,
        "preserveConstEnums": true,
        "sourceMap": true
      },
      "files": [
        "core.ts",
        "sys.ts",
        "types.ts",
        "scanner.ts",
        "parser.ts",
        "utilities.ts",
        "binder.ts",
        "checker.ts",
        "emitter.ts",
        "program.ts",
        "commandLineParser.ts",
        "tsc.ts",
        "diagnosticInformationMap.generated.ts"
      ]
    }
  

tsconfig.json: using the "include" and "exclude" properties


    {
      "compilerOptions": {
        "module": "system",
        "noImplicitAny": true,
        "removeComments": true,
        "preserveConstEnums": true,
        "outFile": "../../built/local/tsc.js",
        "sourceMap": true
      },
      "include": [
        "src/**/*"
      ],
      "exclude": [
        "node_modules",
        "**/*.spec.ts"
      ]
    }
  

override a specific built-in lib


    // when deciding which lib files TS should include,
    // it will first look for a scoped @typescript/lib-* package in node_modules
    // when including 'dom' as an option in lib,
    // TS will use the types in node_modules/@typescript/lib-dom if available
    // install a specific package to take over for a given lib,
    // lock project to a specific version of the DOM APIs:
    {
      "dependencies": {
        "@typescript/lib-dom": "npm:@types/web"
      }
    }
  

ECMAScript Module Support (ESM) in Node.js


    // tsconfig.json
    {
      "compilerOptions": {
        "module": "node16",
        "module": "nodenext",
      }
    }
    // "type" in package.json
    // whether .js files are interpreted as ES modules or CommonJS modules, and defaults to CommonJS when not set
    {
        "name": "my-package",
        "type": "module",
        "type": "commonjs",
        "//": "...",
        "dependencies": {
        }
    }

    // ./foo.ts
    export function helper() {
      // ...
    }
    // ./bar.ts
    import { helper } from "./foo"; // only works in CJS only !
    import { helper } from "./foo.js"; // works in ESM & CJS
    helper();

    // - Node.js allows ES modules to import CommonJS modules as if they were ES modules with a default export
    // ./foo.cts
    export function helper() {
      console.log("hello world!");
    }
    // ./bar.mts
    import foo from "./foo.cjs";
    foo.helper(); // prints "hello world!"
    // - in some cases, Node.js also synthesizes named exports from CommonJS modules
    // ES modules can use a “namespace-style” import (i.e. import * as foo from "..."), or named imports (i.e. import { helper } from "...")
    // ./bar.mts
    import { helper } from "./foo.cjs";
    helper(); // prints "hello world!"

    // --- package.json - exports, imports, and self-referencing (read NodeJS/package.json section)
    // separate entry-points for CommonJS and ESM
    {
      "name": "my-package",
      "type": "module",
      "exports": {
        ".": {
          "import": "./esm/index.js", // Entry-point for `import "my-package"` in ESM
          "require": "./commonjs/index.cjs", // Entry-point for `require("my-package") in CJS
        },
      },
      "main": "./commonjs/index.cjs", // CJS fall-back for older versions of Node.js
    }
    // if "main" pointed to ./lib/index.js, TS would look for a file called ./lib/index.d.ts
    // package author could override this by specifying a separate field called "types" (e.g. "types": "./types/index.d.ts")
    // works similarly with "import" conditions.
    // TS overlays the same rules with import conditions - if you write an "import" from an ES module, it will look up the import field
    // and from a CommonJS module, it will look at the "require" field
    // then look for a corresponding declaration file.
    // add a "types" import condition to point to a different location for your type declarations
    {
      "name": "my-package",
      "type": "module",
      "exports": {
        ".": {
          "import": { // Entry-point for `import "my-package"` in ESM
            "types": "./types/esm/index.d.ts", // Where TS will look
            "default": "./esm/index.js" // Where Node.js will look
          },
          "require": { // Entry-point for `require("my-package") in CJS
            "types": "./types/commonjs/index.d.cts", // Where TS will look
            "default": "./commonjs/index.cjs" // Where Node.js will look
          },
        }
      },
      "types": "./types/index.d.ts", // Fall-back for older versions of TS
      "main": "./commonjs/index.cjs" // CJS fall-back for older versions of Node.js
    }
  

    // if typeRoots is specified, only packages under typeRoots will be included.
    // this example includes all packages under ./typings,
    // and no packages from ./node_modules/@types :
    {
      "compilerOptions": {
        "typeRoots" : ["./typings"]
      }
    }

    // if types is specified, only packages listed will be included.
    // only include ./node_modules/@types/node,
    // ./node_modules/@types/lodash and ./node_modules/@types/express
    // other packages under node_modules/@types/* will not be included :
    {
      "compilerOptions": {
          "types" : ["node", "lodash", "express"]
      }
    }
  

    // --- React jsx and jsxs factory functions

    // --- production builds might look like the following
    // ./src/tsconfig.json
    {
      "compilerOptions": {
        "module": "esnext",
        "target": "es2015",
        "jsx": "react-jsx",
        "strict": true
      },
      "include": ["./**/*"]
    }

    // --- development builds might look like the following
    // ./src/tsconfig.dev.json
    {
      "extends": "./tsconfig.json",
      "compilerOptions": {
        "jsx": "react-jsxdev"
      }
    }
  

Compiller Options

Option Type Default Description
--allowJs boolean false Allow JavaScript files to be compiled
--allowSyntheticDefaultImports boolean module === "system" or --esModuleInterop is set and module is not es2015/esnext Allow default imports from modules with no default export. This does not affect code emit, just typechecking
--allowUnreachableCode boolean false Do not report errors on unreachable code
--allowUmdGlobalAccess boolean false access UMD exports as globals from inside module files, without this flag, using an export from a UMD module requires an import declaration
--allowUnusedLabels boolean false Do not report errors on unused labels
--alwaysStrict boolean false Parse in strict mode and emit "use strict" for each source file
--assumeChangesOnlyAffectDirectDependencies boolean false When enabled, TS will avoid rechecking/rebuilding all truly possibly-affected files, and only recheck/rebuild files that have changed as well as files that directly import them, can be considered a fast&loose implementation of the watching algorithm, which can drastically reduce incremental rebuild times at the expense of having to run the full build occasionally to get all compiler error messages
--baseUrl string   Base directory to resolve non-relative module names. See Module Resolution documentation for more details
--build
-b
boolean false Builds this project and all of its dependencies specified by Project References. Note that this flag is not compatible with others on this page. See more here
--charset string "utf8" The character set of the input files
--checkJs boolean false Report errors in .js files
--declaration
-d
boolean false Generates corresponding .d.ts file
--declarationDir string   Output directory for generated declaration files
--declarationMap boolean false Generates a sourcemap for each corresponding .d.ts file
--diagnostics boolean false Show diagnostic information
--disableSizeLimit boolean false Disable size limitation on JavaScript project
--downlevelIteration boolean false Provide full support for iterables in for..of, spread and destructuring when targeting ES5 or ES3
--emitBOM boolean false Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files
--emitDeclarationOnly boolean false Only emit .d.ts declaration files
--emitDecoratorMetadata[1] boolean false Emit design-type metadata for decorated declarations in source. See issue #2577 for details
--esModuleInterop boolean false Emit __importStar and __importDefault helpers for runtime babel ecosystem compatibility and enable --allowSyntheticDefaultImports for typesystem compatibility
--exactOptionalPropertyTypes[1] boolean false apply stricter rules around how it handles properties on type or interfaces which have a ? prefix, enforce the definition provided as an optional property, no undefined assignment possible: colorThemeOverride?: "dark" | "light";
--experimentalDecorators[1] boolean false Enables experimental support for ES decorators
--explainFiles boolean false Print names of files which TS sees as a part of your project and the reason they are part of the compilation
--extendedDiagnostics boolean false Show verbose diagnostic information
--forceConsistentCasingInFileNames boolean false Disallow inconsistently-cased references to the same file
--help
-h
    Print help message
--importHelpers boolean false Import emit helpers (e.g. __extends, __rest, etc..) from tslib
--importsNotUsedAsValues remove|preserve|error remove controls how import works: remove - dropping import statements which only reference types; preserve - preserves all import statements whose values or types are never used, can cause imports/side-effects to be preserved; error - preserves all imports (the same as the preserve option), but will error when a value import is only used as a type, might be useful to ensure no values are being accidentally imported, but still make side-effect imports explicit
--incremental boolean true if composite is on, false otherwise Enable incremental compilation by reading/writing information from prior compilations to a file on disk. This file is controlled by the --tsBuildInfoFile flag.
--inlineSourceMap boolean false Emit a single file with source maps instead of having a separate file
--inlineSources boolean false Emit the source alongside the sourcemaps within a single file; requires --inlineSourceMap or --sourceMap to be set
--init     Initializes a TS project and creates a tsconfig.json file
--isolatedModules boolean false Transpile each file as a separate module (similar to "ts.transpileModule")
--jsx string "Preserve" Support JSX in .tsx files: "React" or "Preserve". See JSX
--jsxFactory string "React.createElement" Specify the JSX factory function to use when targeting react JSX emit, e.g. React.createElement or h
--keyofStringsOnly boolean false Resolve keyof to string valued property names only (no numbers or symbols)
--lib string[]   List of library files to be included in the compilation
Possible values are:
ES5
ES6
ES2015
ES7
ES2016
ES2017
ES2018
ESNext
DOM
DOM.Iterable
WebWorker
ScriptHost
ES2015.Core
ES2015.Collection
ES2015.Generator
ES2015.Iterable
ES2015.Promise
ES2015.Proxy
ES2015.Reflect
ES2015.Symbol
ES2015.Symbol.WellKnown
ES2016.Array.Include
ES2017.object
ES2017.Intl
ES2017.SharedMemory
ES2017.String
ES2017.TypedArrays
ES2018.Intl
ES2018.Promise
ES2018.RegExp
ES2020
ESNext.AsyncIterable
ESNext.Array
ESNext.Intl
ESNext.Symbol

Note: If --lib is not specified a default list of libraries are injected. The default libraries injected are:
For --target ES5: DOM,ES5,ScriptHost
For --target ES6: DOM,ES6,DOM.Iterable,ScriptHost
--listEmittedFiles boolean false Print names of generated files part of the compilation
--listFiles boolean false Print names of files part of the compilation
--locale string (platform specific) The locale to use to show error messages, e.g. en-us.
Possible values are:
English (US): en
Czech: cs
German: de
Spanish: es
French: fr
Italian: it
Japanese: ja
Korean: ko
Polish: pl
Portuguese(Brazil): pt-BR
Russian: ru
Turkish: tr
Simplified Chinese: zh-CN
Traditional Chinese: zh-TW
--mapRoot string   Specifies the location where debugger should locate map files instead of generated locations. Use this flag if the .map files will be located at run-time in a different location than the .js files. The location specified will be embedded in the sourceMap to direct the debugger where the map files will be located
--maxNodeModuleJsDepth number 0 The maximum dependency depth to search under node_modules and load JavaScript files. Only applicable with --allowJs
--module
-m
string target === "ES3" or "ES5" ? "CommonJS" : "ES6" Specify module code generation: "None", "CommonJS", "AMD", "System", "UMD", "ES6", "ES2015", "ES2020" or "ESNext"
Only "AMD" and "System" can be used in conjunction with --outFile
"ES6" and "ES2015" values may be used when targeting "ES5" or lower
--moduleDetection string auto "auto" - TS will not only look for import and export statements, but it will also check whether the "type" field in a package.json is set to "module" when running with module: nodenext or node16, and check whether the current file is a JSX file when running under jsx: react-jsx. "legacy" - The same behavior as 4.6 and prior, usings import and export statements to determine whether a file is a module. "force" - Ensures that every non-declaration file is treated as a module
--moduleResolution string module === "AMD" or "System" or "ES6" ? "Classic" : "Node" Determine how modules get resolved. Either "Node" for Node.js/io.js style resolution, or "Classic". See Module Resolution documentation for more details
--moduleSuffixes list "" Default list of file name suffixes to search when resolving a module. moduleSuffixes": [".ios", ".native", ""] for import * as foo from "./foo"; will look for the relative files ./foo.ios.ts, ./foo.native.ts, and finally ./foo.ts . Empty string "" in is necessary for TS to also look-up .ts . Can be useful for React Native projects where each target platform can use a separate tsconfig.json with differing moduleSuffixes.
--newLine string (platform specific) Use the specified end of line sequence to be used when emitting files: "crlf" (windows) or "lf" (unix)."
--noEmit boolean false Do not emit outputs
--noEmitHelpers boolean false Do not generate custom helper functions like __extends in compiled output
--noEmitOnError boolean false Do not emit outputs if any errors were reported
--noErrorTruncation boolean false Do not truncate error messages
--noFallthroughCasesInSwitch boolean false Report errors for fallthrough cases in switch statement
--noImplicitAny boolean false Raise error on expressions and declarations with an implied any type
--noImplicitOverride boolean false ensure that the sub-classes never go out of sync, by ensuring that functions which override include the keyword 'override'
--noImplicitReturns boolean false Report error when not all code paths in function return a value
--noImplicitThis boolean false Raise error on this expressions with an implied any type
--noImplicitUseStrict boolean false Do not emit "use strict" directives in module output
--noLib boolean false Do not include the default library file (lib.d.ts)
--noPropertyAccessFromIndexSignature boolean false signal intent in your calling syntax about how certain you are this property exists, true - aise an error because the unknown field uses dot syntax instead of indexed syntax, false - allow to use the dot syntax to access fields which are not defined
--noResolve boolean false Do not add triple-slash references or module import targets to the list of compiled files
--noStrictGenericChecks boolean false Disable strict checking of generic signatures in function types
--noUncheckedIndexedAccess boolean false add undefined to any un-declared field in the type
--noUnusedLocals boolean false Report errors on unused locals
--noUnusedParameters boolean false Report errors on unused parameters
--out string   DEPRECATED. Use --outFile instead
--outDir string   Redirect output structure to the directory
--outFile string   Concatenate and emit output to single file. The order of concatenation is determined by the list of files passed to the compiler on the command line along with triple-slash references and imports. See output file order documentation for more details
paths[2] Object   List of path mapping entries for module names to locations relative to the baseUrl. Can be used without baseUrl. See Module Resolution documentation for more details
--preserveConstEnums boolean false Do not erase const enum declarations in generated code. See const enums documentation for more details
--preserveSymlinks boolean false Do not resolve symlinks to their real path; treat a symlinked file like a real one
--preserveValueImports boolean false If TS cant detect import or code using 'Compiles to HTML' languages like Svelte or Vue, combined with --isolatedModules imported types must be marked as type-only: import { someFunc, type BaseType } from "./some-module.js"; here BaseType is always guaranteed to be erased and someFunc will be preserved
--preserveWatchOutput boolean false Keep outdated console output in watch mode instead of clearing the screen
--pretty boolean true unless piping to another program or redirecting output to a file Stylize errors and messages using color and context
--project
-p
string   Compile a project given a valid configuration file
The argument can be a file path to a valid JSON configuration file, or a directory path to a directory containing a tsconfig.json file
See tsconfig.json documentation for more details
--reactNamespace string "React" DEPRECATED. Use --jsxFactory instead
Specifies the object invoked for createElement and __spread when targeting "react" JSX emit
--removeComments boolean false Remove all comments except copy-right header comments beginning with /*!
--resolveJsonModule boolean false Include modules imported with .json extension
--rootDir string (common root directory is computed from the list of input files) Specifies the root directory of input files. Only use to control the output directory structure with --outDir
rootDirs[2] string[]   List of root folders whose combined content represent the structure of the project at runtime. See Module Resolution documentation for more details
--showConfig boolean false Rather than actually execute a build with the other input options and config files, show the final implied config file in the output
--skipDefaultLibCheck boolean false DEPRECATED. Use --skipLibCheck instead
Skip type checking of default library declaration files
--skipLibCheck boolean false Skip type checking of all declaration files (*.d.ts)
--sourceMap boolean false Generates corresponding .map file
--sourceRoot string   Specifies the location where debugger should locate TS files instead of source locations. Use this flag if the sources will be located at run-time in a different location than that at design-time. The location specified will be embedded in the sourceMap to direct the debugger where the source files will be located
--strict boolean false Enable all strict type checking options.
Enabling --strict enables --noImplicitAny, --noImplicitThis, --alwaysStrict, --strictBindCallApply, --strictNullChecks, --strictFunctionTypes and --strictPropertyInitialization
--strictBindCallApply boolean false Enable stricter checking of of the bind, call, and apply methods on functions
--strictFunctionTypes boolean false Disable bivariant parameter checking for function types
--strictPropertyInitialization boolean false Ensure non-undefined class properties are initialized in the constructor. This option requires --strictNullChecks be enabled in order to take effect
--strictNullChecks boolean false In strict null checking mode, the null and undefined values are not in the domain of every type and are only assignable to themselves and any (the one exception being that undefined is also assignable to void)
--stripInternal[1] boolean false Do not emit declarations for code that has an /** @internal */ JSDoc annotation
--suppressExcessPropertyErrors boolean false Suppress excess property checks for object literals
--suppressImplicitAnyIndexErrors boolean false Suppress --noImplicitAny errors for indexing objects lacking index signatures. See issue #1232 for more details
--target
-t
string "ES3" Specify ECMAScript target version: "ES3" (default), "ES5", "ES6"/"ES2015", "ES2016", "ES2017"..."ES2020" or "ESNext".

Note: "ESNext" targets latest supported ES proposed features
--traceResolution boolean false Report module resolution log messages
--tsBuildInfoFile string .tsbuildinfo Specify what file to store incremental build information in. Files can be safely deleted and don't have any impact on our code at runtime - they're purely used to make compilations faste
--types string[]   List of names of type definitions to include. See @types, -typeRoots and -types for more details
--typeRoots string[]   List of folders to include type definitions from. See @types, -typeRoots and -types for more details
--useDefineForClassFields boolean   switch to the upcoming ECMA class fields runtime behavior
--useUnknownInCatchVariables boolean false changing the type of the variable in a catch clause from any to unknown
--version
-v
    Print the compiler's version
--watch
-w
    Run the compiler in watch mode. Watch input files and trigger recompilation on changes. The implementation of watching files and directories can be configured using environment variable. See configuring watch for more details
--watchDirectory
-w
fixedPollingInterval | dynamicPriorityPolling | useFsEvents useFsEvents strategy for how entire directory trees are watched under systems that lack recursive file-watching functionality: fixedPollingInterval - check every directory for changes several times a second at a fixed interval; dynamicPriorityPolling - use a dynamic queue where less-frequently modified directories will be checked less often; useFsEvents - attempt to use the operating system/file system's native events for directory changes
--watchFile
-w
fixedPollingInterval | priorityPollingInterval | dynamicPriorityPolling | useFsEvents | useFsEventsOnParentDirectory useFsEvents strategy for how individual files are watched: fixedPollingInterval - check every file for changes several times a second at a fixed interval; priorityPollingInterval - check every file for changes several times a second, but use heuristics to check certain types of files less frequently than others; dynamicPriorityPolling - use a dynamic queue where less-frequently modified files will be checked less often; useFsEvents - attempt to use the operating system/file system native events for file changes; useFsEventsOnParentDirectory - attempt to use the operating system/file system native events to listen for changes on a file parent directory
--fallbackPolling
-w
fixedPollingInterval | dynamicPriorityPolling | synchronousWatchDirectory useFsEvents polling strategy that gets used when the system runs out of native file watchers and/or doesnt support native file watchers: fixedPollingInterval - check every file for changes several times a second at a fixed interval; priorityPollingInterval - check every file for changes several times a second, but use heuristics to check certain types of files less frequently than others; dynamicPriorityPolling - use a dynamic queue where less-frequently modified files will be checked less often; synchronousWatchDirectory - disable deferred watching on directories. Deferred watching is useful when lots of file changes might occur at once (e.g. a change in node_modules from running npm install), but you might want to disable it with this flag for some less-common setups

Configuring --watch

with tsconfig.json


    {
      // Some typical compiler options
      "compilerOptions": {
        "target": "es2020",
        "moduleResolution": "node"
        // ...
      },
      // NEW: Options for file/directory watching
      "watchOptions": {
        // Use native file system events for files and directories
        "watchFile": "useFsEvents",
        "watchDirectory": "useFsEvents",
        // Poll files for updates more frequently
        // when they're updated a lot.
        "fallbackPolling": "dynamicPriority",
        // Don't coalesce watch notification
        "synchronousWatchDirectory": true,
        // Finally, two additional settings for reducing the amount of possible
        // files to track  work from these directories
        "excludeDirectories": ["**/node_modules", "_build"],
        "excludeFiles": ["build/fileWhichChangesOften.ts"]
      }
    }
  

Project References


    {
      "compilerOptions": {
        // The usual
      },
      "references": [
        { "path": "../src" }
      ]
    }

    // prepending the output of a dependency using the prepend option in a reference
    // include the project output above the output of the current project
    // works for both .js files and .d.ts
    "references": [
      { "path": "../utils", "prepend": true }
    ]
  

+ Browserify


    // install
    npm install browserify
    npm install TS
    npm install tsify
    // using Command Line Interface
    browserify main.ts -p [ tsify --noImplicitAny ] > bundle.js

    // using API
    var browserify = require("browserify");
    var tsify = require("tsify");
    browserify()
      .add("main.ts")
      .plugin("tsify", { noImplicitAny: true })
      .bundle()
      .on('error', function (error) { console.error(error.toString()); })
      .pipe(process.stdout);
  

+ Grunt


    // install
    npm install grunt-ts

    // basic Gruntfile.js
    module.exports = function(grunt) {
      grunt.initConfig({
        ts: {
          default : {
            src: ["**/*.ts", "!node_modules/**/*.ts"]
            // tsconfig: './tsconfig.json'
          }
        }
      });
      grunt.loadNpmTasks("grunt-ts");
      grunt.registerTask("default", ["ts"]);
    };
  

+ Gulp


    // install gulp CLI
    npm install --global gulp-cli
    // install gulp in the project dependency
    npm install gulp@4
    // Install gulp-TS & TS
    npm install gulp-TS TS
    npm install gulp-TS

    // basic gulpfile.js default task
    var gulp = require("gulp");
    var ts = require("gulp-TS");
    gulp.task("default", function () {
      var tsResult = gulp.src("src/*.ts")
        .pipe(ts({
          noImplicitAny: true,
          out: "output.js"
        }));
      return tsResult.js.pipe(gulp.dest("built/local"));
    });

    // file specifies custom named task
    var gulp = require('gulp');
    var ts = require('gulp-TS');
    var merge = require('merge2');  // Requires separate installation
    gulp.task('scripts', function() {
      var tsResult = gulp.src('lib/**/*.ts')
      .pipe(ts({
          declaration: true
      }));
      return merge([
        tsResult.dts.pipe(gulp.dest('release/definitions')),
        tsResult.js.pipe(gulp.dest('release/js'))
      ]);
    });

    // incremental compilation
    var gulp = require('gulp');
    var ts = require('gulp-TS');
    var merge = require('merge2');
    var tsProject = ts.createProject({
      declaration: true
    });
    gulp.task('scripts', function() {
      return gulp.src('lib/*.ts')
        .pipe(tsProject())
        .pipe(gulp.dest('dist'));
    });
    gulp.task('watch', ['scripts'], function() {
      gulp.watch('lib/*.ts', ['scripts']);
    });

    // using tsconfig.json
    var tsProject = ts.createProject('tsconfig.json');
    // if you want to add/overwrite certain settings in the tsconfig.json file, you can use:
    var tsProject = ts.createProject('tsconfig.json', { noImplicitAny: true });
    // task will look like:
    gulp.task('scripts', function() {
      var tsResult = gulp.src("lib/**/*.ts") // or tsProject.src()
        .pipe(tsProject());
      return tsResult.js.pipe(gulp.dest('release'));
    });
    // you can replace gulp.src(...) with tsProject.src()
    // to load files based on the tsconfig file (based on files, excludes and includes)

    // source maps
    var gulp = require('gulp')
    var ts = require('gulp-TS');
    var sourcemaps = require('gulp-sourcemaps');
    gulp.task('scripts', function() {
      return gulp.src('lib/*.ts')
        .pipe(sourcemaps.init()) // This means sourcemaps will be generated
        .pipe(ts({
            // ...
        }))
        .pipe( ... ) // You can use other plugins that also support gulp-sourcemaps
        .pipe(sourcemaps.write()) // Now the sourcemaps are added to the .js file
        .pipe(gulp.dest('dist'));
    });
  

+ Webpack


    // install
    npm install ts-loader --save-dev
    // basic webpack.config.js
    // for easier debug:
    // npm install awesome-TS-loader source-map-loader
    module.exports = {
      entry: "./src/index.tsx",
      output: {
        filename: "bundle.js"
      },
      // Enable sourcemaps for debugging webpack output:
      // devtool: "source-map",
      resolve: {
        // Add '.ts' and '.tsx' as a resolvable extension.
        extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
      },
      module: {
        loaders: [
          // all files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'
          { test: /\.tsx?$/, loader: "ts-loader" }
          // { test: /\.tsx?$/, loader: "awesome-TS-loader" }
        ],
        preLoaders: [
          // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
          { test: /\.js$/, loader: "source-map-loader" }
        ]
      }
    }
  

Gulp project


    mkdir proj
    cd proj
    mkdir src
    mkdir dist

    npm init # turn this folder into an npm package
    # will ask for settings
    # you can use the defaults except for your entry point
    # for your entry point, use ./dist/main.js

    # generated, working directory
    proj/
    +-- src/
    |   +-- main.ts
    |   +-- greet.ts
    |   +-- index.html
    +-- dist/
    +-- node_modules/...
    +-- tsconfig.json # create
    +-- gulpfile.js # create
    +-- package.json
    +-- package-lock.json

    #
    npm install -g gulp-cli
    npm install --save-dev TS gulp gulp-TS
    # test after creating/changing files
    gulp
    node dist/main.js
    # open: dist/index.html in browser
  

tsconfig.json


    {
      "files": [
        "src/main.ts",
        "src/greet.ts"
      ],
      "compilerOptions": {
        "noImplicitAny": true,
        "target": "es5" // target TS to ES6, for Babel also
      }
    }
  

gulpfile.js


    // npm install --save-dev browserify tsify vinyl-source-stream
    var gulp = require("gulp");
    var browserify = require("browserify"); // bundle all our modules into one JS file
    // transforms Browserify format back gulps (called vinyl)
    var source = require('vinyl-source-stream');
    var tsify = require("tsify"); // plugin for compiling TS
    // npm install --save-dev watchify gulp-util
    var watchify = require("watchify");
    var gutil = require("gulp-util");
    // npm install --save-dev gulp-uglify vinyl-buffer gulp-sourcemaps
    var uglify = require('gulp-uglify');
    var sourcemaps = require('gulp-sourcemaps');
    var buffer = require('vinyl-buffer');
    var paths = {
      pages: ['src/*.html']
    };

    // --- WATCH FOR CHANGES AND REGENERATE BUNDLE
    var watchedBrowserify = watchify(browserify({
      basedir: '.',

      // to debug original TS in the browser instead of bundled JS
      // emit source maps inside the bundled JS file
      debug: true,

      entries: ['src/main.ts'],
      cache: {},
      packageCache: {}
    }).plugin(tsify));
    gulp.task("copy-html", function () {
        return gulp.src(paths.pages)
            .pipe(gulp.dest("dist"));
    });
    function bundle() {
        return watchedBrowserify
        // --- babelify
        // npm install --save-dev babelify babel-core babel-preset-es2015
        .transform('babelify', {
          presets: ['es2015'],
          extensions: ['.ts'] // allow TS in Babel (defaults: .js, .es, .es6 and .jsx)
          // install other babelify version if required: sudo npm install babelify@8
        })
        // --- --- ---
        .bundle()
        .pipe(source('bundle.js')) // bundled JS
        // --- uglify
        .pipe(buffer())
        .pipe(sourcemaps.init({loadMaps: true}))
        .pipe(uglify())
        .pipe(sourcemaps.write('./'))
        // --- --- ---
        .pipe(gulp.dest("dist"));
    }
    gulp.task("default", gulp.series('copy-html', bundle));
    // gulp.task("default", ["copy-html"], bundle); // gulp 3
    watchedBrowserify.on("update", bundle);
    watchedBrowserify.on("log", gutil.log);

    // --- ONE-TIME COMPILATION
    // gulp.task("copy-html", function () {
    //     return gulp.src(paths.pages)
    //         .pipe(gulp.dest("dist"));
    // });
    // gulp.task("default", gulp.series('copy-html', function(){
    // // gulp.task("default", ["copy-html"], function () { // gulp 3
    //     return browserify({
    //         basedir: '.',
    //         debug: true,
    //         entries: ['src/main.ts'],
    //         cache: {},
    //         packageCache: {}
    //     })
    //     .plugin(tsify)
    //     .bundle()
    //     .pipe(source('bundle.js'))
    //     .pipe(gulp.dest("dist"));
    // }));
  

src/greet.ts


    export function sayHello(name: string) {
      return `Hello from ${name}`;
    }
  

src/main.ts


    import { sayHello } from "./greet";
    function showHello(divName: string, name: string) {
      const elt = document.getElementById(divName);
      elt.innerText = sayHello(name);
    }
    showHello("greeting", "TS");
  

src/index.html


    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <title>Hello World!</title>
      </head>
      <body>
        <p id="greeting">Loading ...</p>
        <script src="bundle.js"></script>
      </body>
    </html>
  

autogenerated package.json


    {
      "name": "proj",
      "version": "1.0.0",
      "main": "./dist/main.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "description": "",
      "devDependencies": {
        "babel-core": "^6.26.3",
        "babel-preset-es2015": "^6.24.1",
        "babelify": "^8.0.0",
        "browserify": "^16.2.3",
        "gulp": "^4.0.0",
        "gulp-sourcemaps": "^2.6.4",
        "gulp-TS": "^5.0.0",
        "gulp-uglify": "^3.0.1",
        "gulp-util": "^3.0.8",
        "tsify": "^4.0.1",
        "TS": "^3.2.4",
        "vinyl-buffer": "^1.0.1",
        "vinyl-source-stream": "^2.0.0",
        "watchify": "^3.11.0"
      }
    }
  

Back to Main Page