// --- 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
/*
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;
// 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;
// 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 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 */
// 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) { /*...*/ }
// 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
// explicitly specify the type of "this", when compiler is unable
/**
* @this {HTMLElement}
* @param {*} e
*/
function callbackForLater(e) {
this.clientHeight = parseInt(e) // should be fine!
}
// 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 { /*...*/ }
// 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,
}
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(); }
// 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
{ "name": "browserify-TS-extension", "author": "Vandelay Industries", "version": "1.0.0", "main": "./lib/main.js", "types": "./lib/main.d.ts", "dependencies": { "browserify": "latest", "@types/browserify": "latest", "TS": "next" } }
// --- 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
// 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
// --- 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");
}
}
// --- 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;
// 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;
}
// 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;
}
}
// 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;
}
// 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;
}
}
// 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);
}
// 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;
}
}
// 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 { };
.mjs
files are always ES modules, and .cjs
files are always CommonJS modules.mts
and .cts
- TS emits these to .mjs and .cjs respectively.d.mts
and .d.cts
- TS generates declaration files for .mts and .cts, their corresponding extensions will be .d.mts and .d.cts
{
"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"
]
}
{
"compilerOptions": {
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outFile": "../../built/local/tsc.js",
"sourceMap": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
// 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"
}
}
// 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"
}
}
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 fileSee tsconfig.json documentation for more details |
|
--reactNamespace |
string |
"React" |
DEPRECATED. Use --jsxFactory insteadSpecifies 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 insteadSkip 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 |
TSC_WATCHFILE
PriorityPollingInterval
- Use fs.watchFile but use different polling intervals for source files, config files and missing filesDynamicPriorityPolling
- Use a dynamic queue where in the frequently modified files will be polled at shorter interval and the files unchanged will be polled less frequentlyUseFsEvents
- Use fs.watch which uses file system events (but might not be accurate on different OS) to get the notifications for the file changes/creation/deletion. Note that few OS e.g. linux has limit on number of watches and failing to create watcher using fs.watch will result it in creating using fs.watchFileUseFsEventsWithFallbackDynamicPolling
- This option is similar to UseFsEvents except on failing to create watch using fs.watch, the fallback watching happens through dynamic polling queues (as explained in DynamicPriorityPolling)UseFsEventsOnParentDirectory
- This option watches parent directory of the file with fs.watch (using file system events) thus being low on CPU but can compromise accuracy.TSC_WATCHDIRECTORY
, on platforms that dont support recursive directory watching natively in NodeJS, is supported through recursively creating directory watcher for the child directories using different options. Ignored on platforms that support native recursive directory watching (e.g windows).
RecursiveDirectoryUsingFsWatchFile
- Use fs.watchFile to watch the directories and child directories which is a polling watch (consuming CPU cycles)RecursiveDirectoryUsingDynamicPriorityPolling
- Use dynamic polling queue to poll changes to the directory and child directories.
{
// 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"]
}
}
{
"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 }
]
// 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);
// 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"]);
};
// 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'));
});
// 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" }
]
}
}
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
{
"files": [
"src/main.ts",
"src/greet.ts"
],
"compilerOptions": {
"noImplicitAny": true,
"target": "es5" // target TS to ES6, for Babel also
}
}
// 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"));
// }));
export function sayHello(name: string) {
return `Hello from ${name}`;
}
import { sayHello } from "./greet";
function showHello(divName: string, name: string) {
const elt = document.getElementById(divName);
elt.innerText = sayHello(name);
}
showHello("greeting", "TS");
<!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>
{
"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"
}
}