Daniel Rosenwasser edited this page Aug 16, 2016 · 68 revisions

These changes list where implementation differs between versions as the spec and compiler are simplified and inconsistencies are corrected.

For breaking changes to the compiler/services API, please check the API Breaking Changes page.

TypeScript 2.0

For full list of breaking changes see the breaking change issues.

No type narrowing for captured variables in functions and class expressions

Type narrowing does not cross function and class expressions, as well as lambda expressions.

Example

varx: number|string;if(typeofx==="number"){functioninner(): number{returnx;// Error, type of x is not narrowed, c is number | string}vary: number=x;// OK, x is number}

In the previous pattern the compiler can not tell when the callback will execute. Consider:

varx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}x=5;

It is wrong to assume x is a string when x.charAt() is called, as indeed it isn't.

Recommendation

Use constants instead:

constx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}

Generic type parameters are now narrowed

Example

functiong<T>(obj: T){vart: T;if(objinstanceofRegExp){t=obj;// RegExp is not assignable to T}}

Recommendation Either declare your locals to be a specific type and not the generic type parameter, or use a type assertion.

Getters with no setters are automatically inferred to be readonly properties

Example

classC{getx(){return0;}}varc=newC();c.x=1;// Error Left-hand side is a readonly property

Recommendation

Define a setter for do not write to the property.

Function declarations not allowed in blocks in strict mode

This is already a run-time error under strict mode. Starting with TypeScript 2.0, it will be flagged as a compile-time error as well.

Example

if(true){functionfoo(){}}export=foo;

Recommendation

Use function expressions instead:

if(true){constfoo=function(){}}

TemplateStringsArray is now immutable

ES2015 tagged templates always pass their tag an immutable array-like object that has a property called raw (which is also immutable). TypeScript names this object the TemplateStringsArray.

Conveniently, TemplateStringsArray was assignable to an Array<string>, so it's possible users took advantage of this to use a shorter type for their tag parameters:

functionmyTemplateTag(strs: string[]){// ...}

However, in TypeScript 2.0, the language now supports the readonly modifier and can express that these objects are immutable. As a result, TemplateStringsArray has also been made immutable, and is no longer assignable to string[].

Recommendation

Use TemplateStringsArray explicitly (or use ReadonlyArray<string>).

TypeScript 1.8

For full list of breaking changes see the breaking change issues.

Modules are now emitted with a "use strict"; prologue

Modules were always parsed in strict mode as per ES6, but for non-ES6 targets this was not respected in the generated code. Starting with TypeScript 1.8, emitted modules are always in strict mode. This shouldn't have any visible changes in most code as TS considers most strict mode errors as errors at compile time, but it means that some things which used to silently fail at runtime in your TS code, like assigning to NaN, will now loudly fail. You can reference the MDN Article on strict mode for a detailed list of the differences between strict mode and non-strict mode.

To disable this behavior, pass --noImplicitUseStrict on the command line or set it in your tsconfig.json file.

Exporting non-local names from a module

In accordance with the ES6/ES2015 spec, it is an error to export a non-local name from a module.

Example

export{Promise};// Error

Recommendation

Use a local variable declaration to capture the global name before exporting it.

constlocalPromise=Promise;export{localPromiseasPromise};

Reachability checks are enabled by default

In TypeScript 1.8 we've added a set of reachability checks to prevent certain categories of errors. Specifically

  1. check if code is reachable (enabled by default, can be disabled via allowUnreachableCode compiler option)

    functiontest1(){return1;return2;// error here}functiontest2(x){if(x){return1;}else{thrownewError("NYI")}vary=1;// error here}
  2. check if label is unused (enabled by default, can be disabled via allowUnusedLabels compiler option)

    l: // error will be reported - label `l` is unusedwhile(true){}(x)=>{x:x}// error will be reported - label `x` is unused
  3. check if all code paths in function with return type annotation return some value (disabled by default, can be enabled via noImplicitReturns compiler option)

    // error will be reported since function does not return anything explicitly when `x` is falsy.functiontest(x): number{if(x)return10;}
  4. check if control flow falls through cases in switch statement (disabled by default, can be enabled via noFallthroughCasesInSwitch compiler option). Note that cases without statements are not reported.

    switch(x){// OKcase1: case2: return1;}switch(x){case1:
    if(y)return1;case2: return2;}

If these errors are showing up in your code and you still think that scenario when they appear is legitimate you can suppress errors with compiler options.

--module is not allowed alongside --outFile unless --module is specified as one of amd or system.

Previously specifying both while using modules would result in an empty out file and no error.

Changes to DOM API's in the standard library

  • ImageData.data is now of type Uint8ClampedArray instead of number[]. See #949 for more details.
  • HTMLSelectElement .options is now of type HTMLCollection instead of HTMLSelectElement. See #1558 for more details.
  • HTMLTableElement.createCaption, HTMLTableElement.createTBody, HTMLTableElement.createTFoot, HTMLTableElement.createTHead, HTMLTableElement.insertRow, HTMLTableSectionElement.insertRow, and HTMLTableElement.insertRow now return HTMLTableRowElement instead of HTMLElement. See #3583 for more details.
  • HTMLTableRowElement.insertCell now return HTMLTableCellElement instead of HTMLElement. See #3583 for more details.
  • IDBObjectStore.createIndex and IDBDatabase.createIndex second argument is now of type IDBObjectStoreParameters instead of any. See #5932 for more details.
  • DataTransferItemList.Item returns type now is DataTransferItem instead of File. See #6106 for more details.
  • Window.open return type now is Window instead of any. See #6418 for more details.
  • WeakMap.clear as removed. See #6500 for more details.

Disallow this accessing before super-call

ES6 disallows accessing this in a constructor declaration.

For example:

classB{constructor(that?: any){}}classCextendsB{constructor(){super(this);// error;}}classDextendsB{private_prop1: number;constructor(){this._prop1=10;// errorsuper();}}

TypeScript 1.7

For full list of breaking changes see the breaking change issues.

Changes in inferring the type from this

In a class, the type of the value this will be inferred to the this type. This means subsequent assignments from values the original type can fail.

Example:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest=this;if(Math.rand()<0.5){theVeryBest=opponent;// error}returntheVeryBest}}

Recommendations:

Add a type annotation:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest: Fighter=this;if(Math.rand()<0.5){theVeryBest=opponent;// no error}returntheVeryBest}}

Automatic semicolon insertion after class member modifiers

The keywords abstract, public, protected and private are FutureReservedWords in ECMAScript 3 and are subject to automatic semicolon insertion. Previously, TypeScript did not insert semicolons when these keywords were on their own line. Now that this is fixed, abstract class D no longer correctly extends C in the following example, and instead declares a concrete method m and an additional property named abstract.

Note that async and declare already correctly did ASI.

Example:

abstractclassC{abstractm(): number;}abstractclassDextendsC{abstractm(): number;}

Recommendations:

Remove line breaks after keywords when defining class members. In general, avoid relying on automatic semicolon insertion.

TypeScript 1.6

For full list of breaking changes see the breaking change issues.

Strict object literal assignment checking

It is an error to specify properties in an object literal that were not specified on the target type, when assigned to a variable or passed for a parameter of a non-empty target type.

This new strictness can be disabled with the --suppressExcessPropertyErrors compiler option.

Example:

varx: {foo: number};x={foo: 1,baz: 2};// Error, excess property `baz`vary: {foo: number,bar?: number};y={foo: 1,baz: 2};// Error, excess or misspelled property `baz`

Recommendations:

To avoid the error, there are few remedies based on the situation you are looking into:

If the target type accepts additional properties, add an indexer:

varx: {foo: number,[x: string]: any};x={foo: 1,baz: 2};// OK, `baz` matched by index signature

If the source types are a set of related types, explicitly specify them using union types instead of just specifying the base type.

letanimalList: (Dog|Cat|Turkey)[]=[// use union type instead of Animal{name: "Milo",meow: true},{name: "Pepper",bark: true},{name: "koko",gobble: true}];

Otherwise, explicitly cast to the target type to avoid the warning message:

interfaceFoo{foo: number;}interfaceFooBar{foo: number;bar: number;}vary: Foo;y=<FooBar>{foo: 1,bar: 2};

CommonJS module resolution no longer assumes paths are relative

Previously, for the files one.ts and two.ts, an import of "one" in two.ts would resolve to one.ts if they resided in the same directory.

In TypeScript 1.6, "one" is no longer equivalent to "./one" when compiling with CommonJS. Instead, it is searched as relative to an appropriate node_modules folder as would be resolved by runtimes such as Node.js. For details, see the issue that describes the resolution algorithm.

Example:

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"one";

Recommendations:

Fix any non-relative import names that were unintended (strongly suggested).

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"./one";

Set the --moduleResolution compiler option to classic.

Function and class default export declarations can no longer merge with entities intersecting in their meaning

Declaring an entity with the same name and in the same space as a default export declaration is now an error; for example,

exportdefaultfunctionfoo(){}namespacefoo{varx=100;}

and

exportdefaultclassFoo{a: number;}interfaceFoo{b: string;}

both cause an error.

However, in the following example, merging is allowed because the namespace does does not have a meaning in the value space:

exportdefaultclassFoo{}namespaceFoo{}

Recommendations:

Declare a local for your default export and use a separate export default statement as so:

classFoo{a: number;}interfacefoo{b: string;}exportdefaultFoo;

For more details see the originating issue.

Module bodies are parsed in strict mode

In accordance with the ES6 spec, module bodies are now parsed in strict mode. module bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

Changes to DOM API's in the standard library

  • MessageEvent and ProgressEvent constructors now expect arguments; see issue #4295 for more details.
  • ImageData constructor now expects arguments; see issue #4220 for more details.
  • File constructor now expects arguments; see issue #3999 for more details.

System module output uses bulk exports

The compiler uses the new bulk-export variation of the _export function in the System module format that takes any object containing key value pairs (optionally an entire module object for export *) as arguments instead of key, value.

The module loader needs to be updated to v0.17.1 or higher.

.js content of npm package is moved from 'bin' to 'lib' folder

Entry point of TypeScript npm package was moved from bin to lib to unblock scenarios when 'node_modules/typescript/bin/typescript.js' is served from IIS (by default bin is in the list of hidden segments so IIS will block access to this folder).

TypeScript npm package does not install globally by default

TypeScript 1.6 removes the preferGlobal flag from package.json. If you rely on this behaviour please use npm install -g typescript.

Decorators are checked as call expressions

Starting with 1.6, decorators type checking is more accurate; the compiler will checks a decorator expression as a call expression with the decorated entity as a parameter. This can cause error to be reported that were not in previous releases.

TypeScript 1.5

For full list of breaking changes see the breaking change issues.

Referencing arguments in arrow functions is not allowed

This is an alignment with the ES6 semantics of arrow functions. Previously arguments within an arrow function would bind to the arrow function arguments. As per ES6 spec draft 9.2.12, arrow functions do not have an arguments objects. In TypeScript 1.5, the use of arguments object in arrow functions will be flagged as an error to ensure your code ports to ES6 with no change in semantics.

Example:

functionf(){return()=>arguments;// Error: The 'arguments' object cannot be referenced in an arrow function. }

Recommendations:

// 1. Use named rest args functionf(){return(...args)=>{args;}}// 2. Use function expressions insteadfunctionf(){returnfunction(){arguments;}}

Enum reference in-lining changes

For regular enums, pre 1.5, the compiler only inline constant members, and a member was only constant if its initializer was a literal. That resulted in inconsistent behavior depending on whether the enum value is initalized with a literal or an expression. Starting with Typescript 1.5 all non-const enum members are not inlined.

Example:

varx=E.a;// previously inlined as "var x = 1; /*E.a*/"enumE{a=1}

Recommendation: Add the const modifier to the enum declaration to ensure it is consistently inlined at all consumption sites.

For more details see issue #2183.

Contextual type flows through super and parenthesized expressions

Prior to this release, contextual types did not flow through parenthesized expressions. This has forced explicit type casts, especially in cases where parentheses are required to make an expression parse.

In the examples below, m will have a contextual type, where previously it did not.

varx: SomeType=(n)=>((m)=>q);vary: SomeType=t ? (m=>m.length) : undefined;classCextendsCBase<string>{constructor(){super({method(m){returnm.length;}});}}

See issues #1425 and #920 for more details.

DOM interface changes

TypeScript 1.5 refreshes the DOM types in lib.d.ts. This is the first major refresh since TypeScript 1.0; many IE-specific definitions have been removed in favor of the standard DOM definitions, as well as adding missing types like Web Audio and touch events.

Workaround:

You can keep using older versions of the library with newer version of the compiler. You will need to include a local copy of a previous version in your project. Here is the last released version before this change (TypeScript 1.5-alpha).

Here is a list of changes:

  • Property selection is removed from type Document
  • Property clipboardData is removed from type Window
  • Removed interface MSEventAttachmentTarget
  • Properties onresize, disabled, uniqueID, removeNode, fireEvent, currentStyle, runtimeStyle are removed from type HTMLElement
  • Property url is removed from type Event
  • Properties execScript, navigate, item are removed from type Window
  • Properties documentMode, parentWindow, createEventObject are removed from type Document
  • Property parentWindow is removed from type HTMLDocument
  • Property setCapture does not exist anywhere now
  • Property releaseCapture does not exist anywhere now
  • Properties setAttribute, styleFloat, pixelLeft are removed from type CSSStyleDeclaration
  • Property selectorText is removed from type CSSRule
  • CSSStyleSheet.rules is of type CSSRuleList instead of MSCSSRuleList
  • documentElement is of type Element instead of HTMLElement
  • Event has a new required property returnValue
  • Node has a new required property baseURI
  • Element has a new required property classList
  • Location has a new required property origin
  • Properties MSPOINTER_TYPE_MOUSE, MSPOINTER_TYPE_TOUCH are removed from type MSPointerEvent
  • CSSStyleRule has a new required property readonly
  • Property execUnsafeLocalFunction is removed from type MSApp
  • Global method toStaticHTML is removed
  • HTMLCanvasElement.getContext now returns CanvasRenderingContext2D | WebGLRenderingContex
  • Removed extension types Dataview, Weakmap, Map, Set
  • XMLHttpRequest.send has two overloads send(data?: Document): void; and send(data?: String): void;
  • window.orientation is of type string instead of number
  • IE-specific attachEvent and detachEvent are removed from Window

Here is a list of libraries that are partly or entirely replaced by the added DOM types:

  • DefinitelyTyped/auth0/auth0.d.ts
  • DefinitelyTyped/gamepad/gamepad.d.ts
  • DefinitelyTyped/interactjs/interact.d.ts
  • DefinitelyTyped/webaudioapi/waa.d.ts
  • DefinitelyTyped/webcrypto/WebCrypto.d.ts

For more details, please see the full change.

Class bodies are parsed in strict mode

In accordance with the ES6 spec, class bodies are now parsed in strict mode. Class bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

TypeScript 1.4

For full list of breaking changes see the breaking change issues.

See issue #868 for more details about breaking changes related to Union Types

Multiple Best Common Type Candidates

Given multiple viable candidates from a Best Common Type computation we now choose an item (depending on the compiler's implementation) rather than the first item.

vara: {x: number;y?: number};varb: {x: number;z?: number};// was { x: number; z?: number; }[]// now { x: number; y?: number; }[]varbs=[b,a];

This can happen in a variety of circumstances. A shared set of required properties and a disjoint set of other properties (optional or otherwise), empty types, compatible signature types (including generic and non-generic signatures when type parameters are stamped out with any).

Recommendation Provide a type annotation if you need a specific type to be chosen

varbs: {x: number;y?: number;z?: number}[]=[b,a];

Generic Type Inference

Using different types for multiple arguments of type T is now an error, even with constraints involved:

declarefunctionfoo<T>(x: T,y:T): T;varr=foo(1,"");// r used to be {}, now this is an error

With constraints:

interfaceAnimal{x}interfaceGiraffeextendsAnimal{y}interfaceElephantextendsAnimal{z}functionf<TextendsAnimal>(x: T,y: T): T{returnundefined;}varg: Giraffe;vare: Elephant;f(g,e);

See https://github.com/Microsoft/TypeScript/pull/824#discussion_r18665727 for explanation.

Recommendations Specify an explicit type parameter if the mismatch was intentional:

varr=foo<{}>(1,"");// Emulates 1.0 behaviorvarr=foo<string|number>(1,"");// Most usefulvarr=foo<any>(1,"");// Easiestf<Animal>(g,e);

or rewrite the function definition to specify that mismatches are OK:

declarefunctionfoo<T,U>(x: T,y:U): T|U;functionf<TextendsAnimal,UextendsAnimal>(x: T,y: U): T|U{returnundefined;}

Generic Rest Parameters

You cannot use heterogeneous argument types anymore:

functionmakeArray<T>(...items: T[]): T[]{returnitems;}varr=makeArray(1,"");// used to return {}[], now an error

Likewise for new Array(...)

Recommendations Declare a back-compat signature if the 1.0 behavior was desired:

functionmakeArray<T>(...items: T[]): T[];functionmakeArray(...items: {}[]): {}[];functionmakeArray<T>(...items: T[]): T[]{returnitems;}

Overload Resolution with Type Argument Inference

varf10: <T>(x: T,b: ()=>(a: T)=>void,y: T)=>T;varr9=f10('',()=>(a=>a.foo),1);// r9 was any, now this is an error

Recommendations Manually specify a type parameter

varr9=f10<any>('',()=>(a=>a.foo),1);

Strict Mode Parsing for Class Declarations and Class Expressions

ECMAScript 2015 Language Specification (ECMA-262 6th Edition) specifies that ClassDeclaration and ClassExpression are strict mode productions. Thus, additional restrictions will be applied when parsing a class declaration or class expression.

Examples:

classimplements{}// Invalid: implements is a reserved word in strict modeclassC{foo(arguments: any){// Invalid: "arguments" is not allow as a function argumentvareval=10;// Invalid: "eval" is not allowed as the left-hand-side expressionarguments=[];// Invalid: arguments object is immutable}}

For complete list of strict mode restrictions, please see Annex C - The Strict Mode of ECMAScript of ECMA-262 6th Edition.

TypeScript 1.1

For full list of breaking changes see the breaking change issues.

Working with null and undefined in ways that are observably incorrect is now an error

Examples:

varResultIsNumber17=+(null+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.varResultIsNumber18=+(null+null);// Operator '+' cannot be applied to types 'null' and 'null'.varResultIsNumber19=+(undefined+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.

Similarly, using null and undefined directly as objects that have methods now is an error

Examples:

null.toBAZ();undefined.toBAZ();

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Daniel Rosenwasser edited this page Aug 16, 2016 · 68 revisions

These changes list where implementation differs between versions as the spec and compiler are simplified and inconsistencies are corrected.

For breaking changes to the compiler/services API, please check the API Breaking Changes page.

TypeScript 2.0

For full list of breaking changes see the breaking change issues.

No type narrowing for captured variables in functions and class expressions

Type narrowing does not cross function and class expressions, as well as lambda expressions.

Example

varx: number|string;if(typeofx==="number"){functioninner(): number{returnx;// Error, type of x is not narrowed, c is number | string}vary: number=x;// OK, x is number}

In the previous pattern the compiler can not tell when the callback will execute. Consider:

varx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}x=5;

It is wrong to assume x is a string when x.charAt() is called, as indeed it isn't.

Recommendation

Use constants instead:

constx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}

Generic type parameters are now narrowed

Example

functiong<T>(obj: T){vart: T;if(objinstanceofRegExp){t=obj;// RegExp is not assignable to T}}

Recommendation Either declare your locals to be a specific type and not the generic type parameter, or use a type assertion.

Getters with no setters are automatically inferred to be readonly properties

Example

classC{getx(){return0;}}varc=newC();c.x=1;// Error Left-hand side is a readonly property

Recommendation

Define a setter for do not write to the property.

Function declarations not allowed in blocks in strict mode

This is already a run-time error under strict mode. Starting with TypeScript 2.0, it will be flagged as a compile-time error as well.

Example

if(true){functionfoo(){}}export=foo;

Recommendation

Use function expressions instead:

if(true){constfoo=function(){}}

TemplateStringsArray is now immutable

ES2015 tagged templates always pass their tag an immutable array-like object that has a property called raw (which is also immutable). TypeScript names this object the TemplateStringsArray.

Conveniently, TemplateStringsArray was assignable to an Array<string>, so it's possible users took advantage of this to use a shorter type for their tag parameters:

functionmyTemplateTag(strs: string[]){// ...}

However, in TypeScript 2.0, the language now supports the readonly modifier and can express that these objects are immutable. As a result, TemplateStringsArray has also been made immutable, and is no longer assignable to string[].

Recommendation

Use TemplateStringsArray explicitly (or use ReadonlyArray<string>).

TypeScript 1.8

For full list of breaking changes see the breaking change issues.

Modules are now emitted with a "use strict"; prologue

Modules were always parsed in strict mode as per ES6, but for non-ES6 targets this was not respected in the generated code. Starting with TypeScript 1.8, emitted modules are always in strict mode. This shouldn't have any visible changes in most code as TS considers most strict mode errors as errors at compile time, but it means that some things which used to silently fail at runtime in your TS code, like assigning to NaN, will now loudly fail. You can reference the MDN Article on strict mode for a detailed list of the differences between strict mode and non-strict mode.

To disable this behavior, pass --noImplicitUseStrict on the command line or set it in your tsconfig.json file.

Exporting non-local names from a module

In accordance with the ES6/ES2015 spec, it is an error to export a non-local name from a module.

Example

export{Promise};// Error

Recommendation

Use a local variable declaration to capture the global name before exporting it.

constlocalPromise=Promise;export{localPromiseasPromise};

Reachability checks are enabled by default

In TypeScript 1.8 we've added a set of reachability checks to prevent certain categories of errors. Specifically

  1. check if code is reachable (enabled by default, can be disabled via allowUnreachableCode compiler option)

    functiontest1(){return1;return2;// error here}functiontest2(x){if(x){return1;}else{thrownewError("NYI")}vary=1;// error here}
  2. check if label is unused (enabled by default, can be disabled via allowUnusedLabels compiler option)

    l: // error will be reported - label `l` is unusedwhile(true){}(x)=>{x:x}// error will be reported - label `x` is unused
  3. check if all code paths in function with return type annotation return some value (disabled by default, can be enabled via noImplicitReturns compiler option)

    // error will be reported since function does not return anything explicitly when `x` is falsy.functiontest(x): number{if(x)return10;}
  4. check if control flow falls through cases in switch statement (disabled by default, can be enabled via noFallthroughCasesInSwitch compiler option). Note that cases without statements are not reported.

    switch(x){// OKcase1: case2: return1;}switch(x){case1:
    if(y)return1;case2: return2;}

If these errors are showing up in your code and you still think that scenario when they appear is legitimate you can suppress errors with compiler options.

--module is not allowed alongside --outFile unless --module is specified as one of amd or system.

Previously specifying both while using modules would result in an empty out file and no error.

Changes to DOM API's in the standard library

  • ImageData.data is now of type Uint8ClampedArray instead of number[]. See #949 for more details.
  • HTMLSelectElement .options is now of type HTMLCollection instead of HTMLSelectElement. See #1558 for more details.
  • HTMLTableElement.createCaption, HTMLTableElement.createTBody, HTMLTableElement.createTFoot, HTMLTableElement.createTHead, HTMLTableElement.insertRow, HTMLTableSectionElement.insertRow, and HTMLTableElement.insertRow now return HTMLTableRowElement instead of HTMLElement. See #3583 for more details.
  • HTMLTableRowElement.insertCell now return HTMLTableCellElement instead of HTMLElement. See #3583 for more details.
  • IDBObjectStore.createIndex and IDBDatabase.createIndex second argument is now of type IDBObjectStoreParameters instead of any. See #5932 for more details.
  • DataTransferItemList.Item returns type now is DataTransferItem instead of File. See #6106 for more details.
  • Window.open return type now is Window instead of any. See #6418 for more details.
  • WeakMap.clear as removed. See #6500 for more details.

Disallow this accessing before super-call

ES6 disallows accessing this in a constructor declaration.

For example:

classB{constructor(that?: any){}}classCextendsB{constructor(){super(this);// error;}}classDextendsB{private_prop1: number;constructor(){this._prop1=10;// errorsuper();}}

TypeScript 1.7

For full list of breaking changes see the breaking change issues.

Changes in inferring the type from this

In a class, the type of the value this will be inferred to the this type. This means subsequent assignments from values the original type can fail.

Example:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest=this;if(Math.rand()<0.5){theVeryBest=opponent;// error}returntheVeryBest}}

Recommendations:

Add a type annotation:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest: Fighter=this;if(Math.rand()<0.5){theVeryBest=opponent;// no error}returntheVeryBest}}

Automatic semicolon insertion after class member modifiers

The keywords abstract, public, protected and private are FutureReservedWords in ECMAScript 3 and are subject to automatic semicolon insertion. Previously, TypeScript did not insert semicolons when these keywords were on their own line. Now that this is fixed, abstract class D no longer correctly extends C in the following example, and instead declares a concrete method m and an additional property named abstract.

Note that async and declare already correctly did ASI.

Example:

abstractclassC{abstractm(): number;}abstractclassDextendsC{abstractm(): number;}

Recommendations:

Remove line breaks after keywords when defining class members. In general, avoid relying on automatic semicolon insertion.

TypeScript 1.6

For full list of breaking changes see the breaking change issues.

Strict object literal assignment checking

It is an error to specify properties in an object literal that were not specified on the target type, when assigned to a variable or passed for a parameter of a non-empty target type.

This new strictness can be disabled with the --suppressExcessPropertyErrors compiler option.

Example:

varx: {foo: number};x={foo: 1,baz: 2};// Error, excess property `baz`vary: {foo: number,bar?: number};y={foo: 1,baz: 2};// Error, excess or misspelled property `baz`

Recommendations:

To avoid the error, there are few remedies based on the situation you are looking into:

If the target type accepts additional properties, add an indexer:

varx: {foo: number,[x: string]: any};x={foo: 1,baz: 2};// OK, `baz` matched by index signature

If the source types are a set of related types, explicitly specify them using union types instead of just specifying the base type.

letanimalList: (Dog|Cat|Turkey)[]=[// use union type instead of Animal{name: "Milo",meow: true},{name: "Pepper",bark: true},{name: "koko",gobble: true}];

Otherwise, explicitly cast to the target type to avoid the warning message:

interfaceFoo{foo: number;}interfaceFooBar{foo: number;bar: number;}vary: Foo;y=<FooBar>{foo: 1,bar: 2};

CommonJS module resolution no longer assumes paths are relative

Previously, for the files one.ts and two.ts, an import of "one" in two.ts would resolve to one.ts if they resided in the same directory.

In TypeScript 1.6, "one" is no longer equivalent to "./one" when compiling with CommonJS. Instead, it is searched as relative to an appropriate node_modules folder as would be resolved by runtimes such as Node.js. For details, see the issue that describes the resolution algorithm.

Example:

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"one";

Recommendations:

Fix any non-relative import names that were unintended (strongly suggested).

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"./one";

Set the --moduleResolution compiler option to classic.

Function and class default export declarations can no longer merge with entities intersecting in their meaning

Declaring an entity with the same name and in the same space as a default export declaration is now an error; for example,

exportdefaultfunctionfoo(){}namespacefoo{varx=100;}

and

exportdefaultclassFoo{a: number;}interfaceFoo{b: string;}

both cause an error.

However, in the following example, merging is allowed because the namespace does does not have a meaning in the value space:

exportdefaultclassFoo{}namespaceFoo{}

Recommendations:

Declare a local for your default export and use a separate export default statement as so:

classFoo{a: number;}interfacefoo{b: string;}exportdefaultFoo;

For more details see the originating issue.

Module bodies are parsed in strict mode

In accordance with the ES6 spec, module bodies are now parsed in strict mode. module bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

Changes to DOM API's in the standard library

  • MessageEvent and ProgressEvent constructors now expect arguments; see issue #4295 for more details.
  • ImageData constructor now expects arguments; see issue #4220 for more details.
  • File constructor now expects arguments; see issue #3999 for more details.

System module output uses bulk exports

The compiler uses the new bulk-export variation of the _export function in the System module format that takes any object containing key value pairs (optionally an entire module object for export *) as arguments instead of key, value.

The module loader needs to be updated to v0.17.1 or higher.

.js content of npm package is moved from 'bin' to 'lib' folder

Entry point of TypeScript npm package was moved from bin to lib to unblock scenarios when 'node_modules/typescript/bin/typescript.js' is served from IIS (by default bin is in the list of hidden segments so IIS will block access to this folder).

TypeScript npm package does not install globally by default

TypeScript 1.6 removes the preferGlobal flag from package.json. If you rely on this behaviour please use npm install -g typescript.

Decorators are checked as call expressions

Starting with 1.6, decorators type checking is more accurate; the compiler will checks a decorator expression as a call expression with the decorated entity as a parameter. This can cause error to be reported that were not in previous releases.

TypeScript 1.5

For full list of breaking changes see the breaking change issues.

Referencing arguments in arrow functions is not allowed

This is an alignment with the ES6 semantics of arrow functions. Previously arguments within an arrow function would bind to the arrow function arguments. As per ES6 spec draft 9.2.12, arrow functions do not have an arguments objects. In TypeScript 1.5, the use of arguments object in arrow functions will be flagged as an error to ensure your code ports to ES6 with no change in semantics.

Example:

functionf(){return()=>arguments;// Error: The 'arguments' object cannot be referenced in an arrow function. }

Recommendations:

// 1. Use named rest args functionf(){return(...args)=>{args;}}// 2. Use function expressions insteadfunctionf(){returnfunction(){arguments;}}

Enum reference in-lining changes

For regular enums, pre 1.5, the compiler only inline constant members, and a member was only constant if its initializer was a literal. That resulted in inconsistent behavior depending on whether the enum value is initalized with a literal or an expression. Starting with Typescript 1.5 all non-const enum members are not inlined.

Example:

varx=E.a;// previously inlined as "var x = 1; /*E.a*/"enumE{a=1}

Recommendation: Add the const modifier to the enum declaration to ensure it is consistently inlined at all consumption sites.

For more details see issue #2183.

Contextual type flows through super and parenthesized expressions

Prior to this release, contextual types did not flow through parenthesized expressions. This has forced explicit type casts, especially in cases where parentheses are required to make an expression parse.

In the examples below, m will have a contextual type, where previously it did not.

varx: SomeType=(n)=>((m)=>q);vary: SomeType=t ? (m=>m.length) : undefined;classCextendsCBase<string>{constructor(){super({method(m){returnm.length;}});}}

See issues #1425 and #920 for more details.

DOM interface changes

TypeScript 1.5 refreshes the DOM types in lib.d.ts. This is the first major refresh since TypeScript 1.0; many IE-specific definitions have been removed in favor of the standard DOM definitions, as well as adding missing types like Web Audio and touch events.

Workaround:

You can keep using older versions of the library with newer version of the compiler. You will need to include a local copy of a previous version in your project. Here is the last released version before this change (TypeScript 1.5-alpha).

Here is a list of changes:

  • Property selection is removed from type Document
  • Property clipboardData is removed from type Window
  • Removed interface MSEventAttachmentTarget
  • Properties onresize, disabled, uniqueID, removeNode, fireEvent, currentStyle, runtimeStyle are removed from type HTMLElement
  • Property url is removed from type Event
  • Properties execScript, navigate, item are removed from type Window
  • Properties documentMode, parentWindow, createEventObject are removed from type Document
  • Property parentWindow is removed from type HTMLDocument
  • Property setCapture does not exist anywhere now
  • Property releaseCapture does not exist anywhere now
  • Properties setAttribute, styleFloat, pixelLeft are removed from type CSSStyleDeclaration
  • Property selectorText is removed from type CSSRule
  • CSSStyleSheet.rules is of type CSSRuleList instead of MSCSSRuleList
  • documentElement is of type Element instead of HTMLElement
  • Event has a new required property returnValue
  • Node has a new required property baseURI
  • Element has a new required property classList
  • Location has a new required property origin
  • Properties MSPOINTER_TYPE_MOUSE, MSPOINTER_TYPE_TOUCH are removed from type MSPointerEvent
  • CSSStyleRule has a new required property readonly
  • Property execUnsafeLocalFunction is removed from type MSApp
  • Global method toStaticHTML is removed
  • HTMLCanvasElement.getContext now returns CanvasRenderingContext2D | WebGLRenderingContex
  • Removed extension types Dataview, Weakmap, Map, Set
  • XMLHttpRequest.send has two overloads send(data?: Document): void; and send(data?: String): void;
  • window.orientation is of type string instead of number
  • IE-specific attachEvent and detachEvent are removed from Window

Here is a list of libraries that are partly or entirely replaced by the added DOM types:

  • DefinitelyTyped/auth0/auth0.d.ts
  • DefinitelyTyped/gamepad/gamepad.d.ts
  • DefinitelyTyped/interactjs/interact.d.ts
  • DefinitelyTyped/webaudioapi/waa.d.ts
  • DefinitelyTyped/webcrypto/WebCrypto.d.ts

For more details, please see the full change.

Class bodies are parsed in strict mode

In accordance with the ES6 spec, class bodies are now parsed in strict mode. Class bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

TypeScript 1.4

For full list of breaking changes see the breaking change issues.

See issue #868 for more details about breaking changes related to Union Types

Multiple Best Common Type Candidates

Given multiple viable candidates from a Best Common Type computation we now choose an item (depending on the compiler's implementation) rather than the first item.

vara: {x: number;y?: number};varb: {x: number;z?: number};// was { x: number; z?: number; }[]// now { x: number; y?: number; }[]varbs=[b,a];

This can happen in a variety of circumstances. A shared set of required properties and a disjoint set of other properties (optional or otherwise), empty types, compatible signature types (including generic and non-generic signatures when type parameters are stamped out with any).

Recommendation Provide a type annotation if you need a specific type to be chosen

varbs: {x: number;y?: number;z?: number}[]=[b,a];

Generic Type Inference

Using different types for multiple arguments of type T is now an error, even with constraints involved:

declarefunctionfoo<T>(x: T,y:T): T;varr=foo(1,"");// r used to be {}, now this is an error

With constraints:

interfaceAnimal{x}interfaceGiraffeextendsAnimal{y}interfaceElephantextendsAnimal{z}functionf<TextendsAnimal>(x: T,y: T): T{returnundefined;}varg: Giraffe;vare: Elephant;f(g,e);

See https://github.com/Microsoft/TypeScript/pull/824#discussion_r18665727 for explanation.

Recommendations Specify an explicit type parameter if the mismatch was intentional:

varr=foo<{}>(1,"");// Emulates 1.0 behaviorvarr=foo<string|number>(1,"");// Most usefulvarr=foo<any>(1,"");// Easiestf<Animal>(g,e);

or rewrite the function definition to specify that mismatches are OK:

declarefunctionfoo<T,U>(x: T,y:U): T|U;functionf<TextendsAnimal,UextendsAnimal>(x: T,y: U): T|U{returnundefined;}

Generic Rest Parameters

You cannot use heterogeneous argument types anymore:

functionmakeArray<T>(...items: T[]): T[]{returnitems;}varr=makeArray(1,"");// used to return {}[], now an error

Likewise for new Array(...)

Recommendations Declare a back-compat signature if the 1.0 behavior was desired:

functionmakeArray<T>(...items: T[]): T[];functionmakeArray(...items: {}[]): {}[];functionmakeArray<T>(...items: T[]): T[]{returnitems;}

Overload Resolution with Type Argument Inference

varf10: <T>(x: T,b: ()=>(a: T)=>void,y: T)=>T;varr9=f10('',()=>(a=>a.foo),1);// r9 was any, now this is an error

Recommendations Manually specify a type parameter

varr9=f10<any>('',()=>(a=>a.foo),1);

Strict Mode Parsing for Class Declarations and Class Expressions

ECMAScript 2015 Language Specification (ECMA-262 6th Edition) specifies that ClassDeclaration and ClassExpression are strict mode productions. Thus, additional restrictions will be applied when parsing a class declaration or class expression.

Examples:

classimplements{}// Invalid: implements is a reserved word in strict modeclassC{foo(arguments: any){// Invalid: "arguments" is not allow as a function argumentvareval=10;// Invalid: "eval" is not allowed as the left-hand-side expressionarguments=[];// Invalid: arguments object is immutable}}

For complete list of strict mode restrictions, please see Annex C - The Strict Mode of ECMAScript of ECMA-262 6th Edition.

TypeScript 1.1

For full list of breaking changes see the breaking change issues.

Working with null and undefined in ways that are observably incorrect is now an error

Examples:

varResultIsNumber17=+(null+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.varResultIsNumber18=+(null+null);// Operator '+' cannot be applied to types 'null' and 'null'.varResultIsNumber19=+(undefined+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.

Similarly, using null and undefined directly as objects that have methods now is an error

Examples:

null.toBAZ();undefined.toBAZ();

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Daniel Rosenwasser edited this page Aug 16, 2016 · 68 revisions

These changes list where implementation differs between versions as the spec and compiler are simplified and inconsistencies are corrected.

For breaking changes to the compiler/services API, please check the API Breaking Changes page.

TypeScript 2.0

For full list of breaking changes see the breaking change issues.

No type narrowing for captured variables in functions and class expressions

Type narrowing does not cross function and class expressions, as well as lambda expressions.

Example

varx: number|string;if(typeofx==="number"){functioninner(): number{returnx;// Error, type of x is not narrowed, c is number | string}vary: number=x;// OK, x is number}

In the previous pattern the compiler can not tell when the callback will execute. Consider:

varx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}x=5;

It is wrong to assume x is a string when x.charAt() is called, as indeed it isn't.

Recommendation

Use constants instead:

constx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}

Generic type parameters are now narrowed

Example

functiong<T>(obj: T){vart: T;if(objinstanceofRegExp){t=obj;// RegExp is not assignable to T}}

Recommendation Either declare your locals to be a specific type and not the generic type parameter, or use a type assertion.

Getters with no setters are automatically inferred to be readonly properties

Example

classC{getx(){return0;}}varc=newC();c.x=1;// Error Left-hand side is a readonly property

Recommendation

Define a setter for do not write to the property.

Function declarations not allowed in blocks in strict mode

This is already a run-time error under strict mode. Starting with TypeScript 2.0, it will be flagged as a compile-time error as well.

Example

if(true){functionfoo(){}}export=foo;

Recommendation

Use function expressions instead:

if(true){constfoo=function(){}}

TemplateStringsArray is now immutable

ES2015 tagged templates always pass their tag an immutable array-like object that has a property called raw (which is also immutable). TypeScript names this object the TemplateStringsArray.

Conveniently, TemplateStringsArray was assignable to an Array<string>, so it's possible users took advantage of this to use a shorter type for their tag parameters:

functionmyTemplateTag(strs: string[]){// ...}

However, in TypeScript 2.0, the language now supports the readonly modifier and can express that these objects are immutable. As a result, TemplateStringsArray has also been made immutable, and is no longer assignable to string[].

Recommendation

Use TemplateStringsArray explicitly (or use ReadonlyArray<string>).

TypeScript 1.8

For full list of breaking changes see the breaking change issues.

Modules are now emitted with a "use strict"; prologue

Modules were always parsed in strict mode as per ES6, but for non-ES6 targets this was not respected in the generated code. Starting with TypeScript 1.8, emitted modules are always in strict mode. This shouldn't have any visible changes in most code as TS considers most strict mode errors as errors at compile time, but it means that some things which used to silently fail at runtime in your TS code, like assigning to NaN, will now loudly fail. You can reference the MDN Article on strict mode for a detailed list of the differences between strict mode and non-strict mode.

To disable this behavior, pass --noImplicitUseStrict on the command line or set it in your tsconfig.json file.

Exporting non-local names from a module

In accordance with the ES6/ES2015 spec, it is an error to export a non-local name from a module.

Example

export{Promise};// Error

Recommendation

Use a local variable declaration to capture the global name before exporting it.

constlocalPromise=Promise;export{localPromiseasPromise};

Reachability checks are enabled by default

In TypeScript 1.8 we've added a set of reachability checks to prevent certain categories of errors. Specifically

  1. check if code is reachable (enabled by default, can be disabled via allowUnreachableCode compiler option)

    functiontest1(){return1;return2;// error here}functiontest2(x){if(x){return1;}else{thrownewError("NYI")}vary=1;// error here}
  2. check if label is unused (enabled by default, can be disabled via allowUnusedLabels compiler option)

    l: // error will be reported - label `l` is unusedwhile(true){}(x)=>{x:x}// error will be reported - label `x` is unused
  3. check if all code paths in function with return type annotation return some value (disabled by default, can be enabled via noImplicitReturns compiler option)

    // error will be reported since function does not return anything explicitly when `x` is falsy.functiontest(x): number{if(x)return10;}
  4. check if control flow falls through cases in switch statement (disabled by default, can be enabled via noFallthroughCasesInSwitch compiler option). Note that cases without statements are not reported.

    switch(x){// OKcase1: case2: return1;}switch(x){case1:
    if(y)return1;case2: return2;}

If these errors are showing up in your code and you still think that scenario when they appear is legitimate you can suppress errors with compiler options.

--module is not allowed alongside --outFile unless --module is specified as one of amd or system.

Previously specifying both while using modules would result in an empty out file and no error.

Changes to DOM API's in the standard library

  • ImageData.data is now of type Uint8ClampedArray instead of number[]. See #949 for more details.
  • HTMLSelectElement .options is now of type HTMLCollection instead of HTMLSelectElement. See #1558 for more details.
  • HTMLTableElement.createCaption, HTMLTableElement.createTBody, HTMLTableElement.createTFoot, HTMLTableElement.createTHead, HTMLTableElement.insertRow, HTMLTableSectionElement.insertRow, and HTMLTableElement.insertRow now return HTMLTableRowElement instead of HTMLElement. See #3583 for more details.
  • HTMLTableRowElement.insertCell now return HTMLTableCellElement instead of HTMLElement. See #3583 for more details.
  • IDBObjectStore.createIndex and IDBDatabase.createIndex second argument is now of type IDBObjectStoreParameters instead of any. See #5932 for more details.
  • DataTransferItemList.Item returns type now is DataTransferItem instead of File. See #6106 for more details.
  • Window.open return type now is Window instead of any. See #6418 for more details.
  • WeakMap.clear as removed. See #6500 for more details.

Disallow this accessing before super-call

ES6 disallows accessing this in a constructor declaration.

For example:

classB{constructor(that?: any){}}classCextendsB{constructor(){super(this);// error;}}classDextendsB{private_prop1: number;constructor(){this._prop1=10;// errorsuper();}}

TypeScript 1.7

For full list of breaking changes see the breaking change issues.

Changes in inferring the type from this

In a class, the type of the value this will be inferred to the this type. This means subsequent assignments from values the original type can fail.

Example:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest=this;if(Math.rand()<0.5){theVeryBest=opponent;// error}returntheVeryBest}}

Recommendations:

Add a type annotation:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest: Fighter=this;if(Math.rand()<0.5){theVeryBest=opponent;// no error}returntheVeryBest}}

Automatic semicolon insertion after class member modifiers

The keywords abstract, public, protected and private are FutureReservedWords in ECMAScript 3 and are subject to automatic semicolon insertion. Previously, TypeScript did not insert semicolons when these keywords were on their own line. Now that this is fixed, abstract class D no longer correctly extends C in the following example, and instead declares a concrete method m and an additional property named abstract.

Note that async and declare already correctly did ASI.

Example:

abstractclassC{abstractm(): number;}abstractclassDextendsC{abstractm(): number;}

Recommendations:

Remove line breaks after keywords when defining class members. In general, avoid relying on automatic semicolon insertion.

TypeScript 1.6

For full list of breaking changes see the breaking change issues.

Strict object literal assignment checking

It is an error to specify properties in an object literal that were not specified on the target type, when assigned to a variable or passed for a parameter of a non-empty target type.

This new strictness can be disabled with the --suppressExcessPropertyErrors compiler option.

Example:

varx: {foo: number};x={foo: 1,baz: 2};// Error, excess property `baz`vary: {foo: number,bar?: number};y={foo: 1,baz: 2};// Error, excess or misspelled property `baz`

Recommendations:

To avoid the error, there are few remedies based on the situation you are looking into:

If the target type accepts additional properties, add an indexer:

varx: {foo: number,[x: string]: any};x={foo: 1,baz: 2};// OK, `baz` matched by index signature

If the source types are a set of related types, explicitly specify them using union types instead of just specifying the base type.

letanimalList: (Dog|Cat|Turkey)[]=[// use union type instead of Animal{name: "Milo",meow: true},{name: "Pepper",bark: true},{name: "koko",gobble: true}];

Otherwise, explicitly cast to the target type to avoid the warning message:

interfaceFoo{foo: number;}interfaceFooBar{foo: number;bar: number;}vary: Foo;y=<FooBar>{foo: 1,bar: 2};

CommonJS module resolution no longer assumes paths are relative

Previously, for the files one.ts and two.ts, an import of "one" in two.ts would resolve to one.ts if they resided in the same directory.

In TypeScript 1.6, "one" is no longer equivalent to "./one" when compiling with CommonJS. Instead, it is searched as relative to an appropriate node_modules folder as would be resolved by runtimes such as Node.js. For details, see the issue that describes the resolution algorithm.

Example:

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"one";

Recommendations:

Fix any non-relative import names that were unintended (strongly suggested).

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"./one";

Set the --moduleResolution compiler option to classic.

Function and class default export declarations can no longer merge with entities intersecting in their meaning

Declaring an entity with the same name and in the same space as a default export declaration is now an error; for example,

exportdefaultfunctionfoo(){}namespacefoo{varx=100;}

and

exportdefaultclassFoo{a: number;}interfaceFoo{b: string;}

both cause an error.

However, in the following example, merging is allowed because the namespace does does not have a meaning in the value space:

exportdefaultclassFoo{}namespaceFoo{}

Recommendations:

Declare a local for your default export and use a separate export default statement as so:

classFoo{a: number;}interfacefoo{b: string;}exportdefaultFoo;

For more details see the originating issue.

Module bodies are parsed in strict mode

In accordance with the ES6 spec, module bodies are now parsed in strict mode. module bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

Changes to DOM API's in the standard library

  • MessageEvent and ProgressEvent constructors now expect arguments; see issue #4295 for more details.
  • ImageData constructor now expects arguments; see issue #4220 for more details.
  • File constructor now expects arguments; see issue #3999 for more details.

System module output uses bulk exports

The compiler uses the new bulk-export variation of the _export function in the System module format that takes any object containing key value pairs (optionally an entire module object for export *) as arguments instead of key, value.

The module loader needs to be updated to v0.17.1 or higher.

.js content of npm package is moved from 'bin' to 'lib' folder

Entry point of TypeScript npm package was moved from bin to lib to unblock scenarios when 'node_modules/typescript/bin/typescript.js' is served from IIS (by default bin is in the list of hidden segments so IIS will block access to this folder).

TypeScript npm package does not install globally by default

TypeScript 1.6 removes the preferGlobal flag from package.json. If you rely on this behaviour please use npm install -g typescript.

Decorators are checked as call expressions

Starting with 1.6, decorators type checking is more accurate; the compiler will checks a decorator expression as a call expression with the decorated entity as a parameter. This can cause error to be reported that were not in previous releases.

TypeScript 1.5

For full list of breaking changes see the breaking change issues.

Referencing arguments in arrow functions is not allowed

This is an alignment with the ES6 semantics of arrow functions. Previously arguments within an arrow function would bind to the arrow function arguments. As per ES6 spec draft 9.2.12, arrow functions do not have an arguments objects. In TypeScript 1.5, the use of arguments object in arrow functions will be flagged as an error to ensure your code ports to ES6 with no change in semantics.

Example:

functionf(){return()=>arguments;// Error: The 'arguments' object cannot be referenced in an arrow function. }

Recommendations:

// 1. Use named rest args functionf(){return(...args)=>{args;}}// 2. Use function expressions insteadfunctionf(){returnfunction(){arguments;}}

Enum reference in-lining changes

For regular enums, pre 1.5, the compiler only inline constant members, and a member was only constant if its initializer was a literal. That resulted in inconsistent behavior depending on whether the enum value is initalized with a literal or an expression. Starting with Typescript 1.5 all non-const enum members are not inlined.

Example:

varx=E.a;// previously inlined as "var x = 1; /*E.a*/"enumE{a=1}

Recommendation: Add the const modifier to the enum declaration to ensure it is consistently inlined at all consumption sites.

For more details see issue #2183.

Contextual type flows through super and parenthesized expressions

Prior to this release, contextual types did not flow through parenthesized expressions. This has forced explicit type casts, especially in cases where parentheses are required to make an expression parse.

In the examples below, m will have a contextual type, where previously it did not.

varx: SomeType=(n)=>((m)=>q);vary: SomeType=t ? (m=>m.length) : undefined;classCextendsCBase<string>{constructor(){super({method(m){returnm.length;}});}}

See issues #1425 and #920 for more details.

DOM interface changes

TypeScript 1.5 refreshes the DOM types in lib.d.ts. This is the first major refresh since TypeScript 1.0; many IE-specific definitions have been removed in favor of the standard DOM definitions, as well as adding missing types like Web Audio and touch events.

Workaround:

You can keep using older versions of the library with newer version of the compiler. You will need to include a local copy of a previous version in your project. Here is the last released version before this change (TypeScript 1.5-alpha).

Here is a list of changes:

  • Property selection is removed from type Document
  • Property clipboardData is removed from type Window
  • Removed interface MSEventAttachmentTarget
  • Properties onresize, disabled, uniqueID, removeNode, fireEvent, currentStyle, runtimeStyle are removed from type HTMLElement
  • Property url is removed from type Event
  • Properties execScript, navigate, item are removed from type Window
  • Properties documentMode, parentWindow, createEventObject are removed from type Document
  • Property parentWindow is removed from type HTMLDocument
  • Property setCapture does not exist anywhere now
  • Property releaseCapture does not exist anywhere now
  • Properties setAttribute, styleFloat, pixelLeft are removed from type CSSStyleDeclaration
  • Property selectorText is removed from type CSSRule
  • CSSStyleSheet.rules is of type CSSRuleList instead of MSCSSRuleList
  • documentElement is of type Element instead of HTMLElement
  • Event has a new required property returnValue
  • Node has a new required property baseURI
  • Element has a new required property classList
  • Location has a new required property origin
  • Properties MSPOINTER_TYPE_MOUSE, MSPOINTER_TYPE_TOUCH are removed from type MSPointerEvent
  • CSSStyleRule has a new required property readonly
  • Property execUnsafeLocalFunction is removed from type MSApp
  • Global method toStaticHTML is removed
  • HTMLCanvasElement.getContext now returns CanvasRenderingContext2D | WebGLRenderingContex
  • Removed extension types Dataview, Weakmap, Map, Set
  • XMLHttpRequest.send has two overloads send(data?: Document): void; and send(data?: String): void;
  • window.orientation is of type string instead of number
  • IE-specific attachEvent and detachEvent are removed from Window

Here is a list of libraries that are partly or entirely replaced by the added DOM types:

  • DefinitelyTyped/auth0/auth0.d.ts
  • DefinitelyTyped/gamepad/gamepad.d.ts
  • DefinitelyTyped/interactjs/interact.d.ts
  • DefinitelyTyped/webaudioapi/waa.d.ts
  • DefinitelyTyped/webcrypto/WebCrypto.d.ts

For more details, please see the full change.

Class bodies are parsed in strict mode

In accordance with the ES6 spec, class bodies are now parsed in strict mode. Class bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

TypeScript 1.4

For full list of breaking changes see the breaking change issues.

See issue #868 for more details about breaking changes related to Union Types

Multiple Best Common Type Candidates

Given multiple viable candidates from a Best Common Type computation we now choose an item (depending on the compiler's implementation) rather than the first item.

vara: {x: number;y?: number};varb: {x: number;z?: number};// was { x: number; z?: number; }[]// now { x: number; y?: number; }[]varbs=[b,a];

This can happen in a variety of circumstances. A shared set of required properties and a disjoint set of other properties (optional or otherwise), empty types, compatible signature types (including generic and non-generic signatures when type parameters are stamped out with any).

Recommendation Provide a type annotation if you need a specific type to be chosen

varbs: {x: number;y?: number;z?: number}[]=[b,a];

Generic Type Inference

Using different types for multiple arguments of type T is now an error, even with constraints involved:

declarefunctionfoo<T>(x: T,y:T): T;varr=foo(1,"");// r used to be {}, now this is an error

With constraints:

interfaceAnimal{x}interfaceGiraffeextendsAnimal{y}interfaceElephantextendsAnimal{z}functionf<TextendsAnimal>(x: T,y: T): T{returnundefined;}varg: Giraffe;vare: Elephant;f(g,e);

See https://github.com/Microsoft/TypeScript/pull/824#discussion_r18665727 for explanation.

Recommendations Specify an explicit type parameter if the mismatch was intentional:

varr=foo<{}>(1,"");// Emulates 1.0 behaviorvarr=foo<string|number>(1,"");// Most usefulvarr=foo<any>(1,"");// Easiestf<Animal>(g,e);

or rewrite the function definition to specify that mismatches are OK:

declarefunctionfoo<T,U>(x: T,y:U): T|U;functionf<TextendsAnimal,UextendsAnimal>(x: T,y: U): T|U{returnundefined;}

Generic Rest Parameters

You cannot use heterogeneous argument types anymore:

functionmakeArray<T>(...items: T[]): T[]{returnitems;}varr=makeArray(1,"");// used to return {}[], now an error

Likewise for new Array(...)

Recommendations Declare a back-compat signature if the 1.0 behavior was desired:

functionmakeArray<T>(...items: T[]): T[];functionmakeArray(...items: {}[]): {}[];functionmakeArray<T>(...items: T[]): T[]{returnitems;}

Overload Resolution with Type Argument Inference

varf10: <T>(x: T,b: ()=>(a: T)=>void,y: T)=>T;varr9=f10('',()=>(a=>a.foo),1);// r9 was any, now this is an error

Recommendations Manually specify a type parameter

varr9=f10<any>('',()=>(a=>a.foo),1);

Strict Mode Parsing for Class Declarations and Class Expressions

ECMAScript 2015 Language Specification (ECMA-262 6th Edition) specifies that ClassDeclaration and ClassExpression are strict mode productions. Thus, additional restrictions will be applied when parsing a class declaration or class expression.

Examples:

classimplements{}// Invalid: implements is a reserved word in strict modeclassC{foo(arguments: any){// Invalid: "arguments" is not allow as a function argumentvareval=10;// Invalid: "eval" is not allowed as the left-hand-side expressionarguments=[];// Invalid: arguments object is immutable}}

For complete list of strict mode restrictions, please see Annex C - The Strict Mode of ECMAScript of ECMA-262 6th Edition.

TypeScript 1.1

For full list of breaking changes see the breaking change issues.

Working with null and undefined in ways that are observably incorrect is now an error

Examples:

varResultIsNumber17=+(null+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.varResultIsNumber18=+(null+null);// Operator '+' cannot be applied to types 'null' and 'null'.varResultIsNumber19=+(undefined+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.

Similarly, using null and undefined directly as objects that have methods now is an error

Examples:

null.toBAZ();undefined.toBAZ();

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Daniel Rosenwasser edited this page Aug 16, 2016 · 68 revisions

These changes list where implementation differs between versions as the spec and compiler are simplified and inconsistencies are corrected.

For breaking changes to the compiler/services API, please check the API Breaking Changes page.

TypeScript 2.0

For full list of breaking changes see the breaking change issues.

No type narrowing for captured variables in functions and class expressions

Type narrowing does not cross function and class expressions, as well as lambda expressions.

Example

varx: number|string;if(typeofx==="number"){functioninner(): number{returnx;// Error, type of x is not narrowed, c is number | string}vary: number=x;// OK, x is number}

In the previous pattern the compiler can not tell when the callback will execute. Consider:

varx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}x=5;

It is wrong to assume x is a string when x.charAt() is called, as indeed it isn't.

Recommendation

Use constants instead:

constx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}

Generic type parameters are now narrowed

Example

functiong<T>(obj: T){vart: T;if(objinstanceofRegExp){t=obj;// RegExp is not assignable to T}}

Recommendation Either declare your locals to be a specific type and not the generic type parameter, or use a type assertion.

Getters with no setters are automatically inferred to be readonly properties

Example

classC{getx(){return0;}}varc=newC();c.x=1;// Error Left-hand side is a readonly property

Recommendation

Define a setter for do not write to the property.

Function declarations not allowed in blocks in strict mode

This is already a run-time error under strict mode. Starting with TypeScript 2.0, it will be flagged as a compile-time error as well.

Example

if(true){functionfoo(){}}export=foo;

Recommendation

Use function expressions instead:

if(true){constfoo=function(){}}

TemplateStringsArray is now immutable

ES2015 tagged templates always pass their tag an immutable array-like object that has a property called raw (which is also immutable). TypeScript names this object the TemplateStringsArray.

Conveniently, TemplateStringsArray was assignable to an Array<string>, so it's possible users took advantage of this to use a shorter type for their tag parameters:

functionmyTemplateTag(strs: string[]){// ...}

However, in TypeScript 2.0, the language now supports the readonly modifier and can express that these objects are immutable. As a result, TemplateStringsArray has also been made immutable, and is no longer assignable to string[].

Recommendation

Use TemplateStringsArray explicitly (or use ReadonlyArray<string>).

TypeScript 1.8

For full list of breaking changes see the breaking change issues.

Modules are now emitted with a "use strict"; prologue

Modules were always parsed in strict mode as per ES6, but for non-ES6 targets this was not respected in the generated code. Starting with TypeScript 1.8, emitted modules are always in strict mode. This shouldn't have any visible changes in most code as TS considers most strict mode errors as errors at compile time, but it means that some things which used to silently fail at runtime in your TS code, like assigning to NaN, will now loudly fail. You can reference the MDN Article on strict mode for a detailed list of the differences between strict mode and non-strict mode.

To disable this behavior, pass --noImplicitUseStrict on the command line or set it in your tsconfig.json file.

Exporting non-local names from a module

In accordance with the ES6/ES2015 spec, it is an error to export a non-local name from a module.

Example

export{Promise};// Error

Recommendation

Use a local variable declaration to capture the global name before exporting it.

constlocalPromise=Promise;export{localPromiseasPromise};

Reachability checks are enabled by default

In TypeScript 1.8 we've added a set of reachability checks to prevent certain categories of errors. Specifically

  1. check if code is reachable (enabled by default, can be disabled via allowUnreachableCode compiler option)

    functiontest1(){return1;return2;// error here}functiontest2(x){if(x){return1;}else{thrownewError("NYI")}vary=1;// error here}
  2. check if label is unused (enabled by default, can be disabled via allowUnusedLabels compiler option)

    l: // error will be reported - label `l` is unusedwhile(true){}(x)=>{x:x}// error will be reported - label `x` is unused
  3. check if all code paths in function with return type annotation return some value (disabled by default, can be enabled via noImplicitReturns compiler option)

    // error will be reported since function does not return anything explicitly when `x` is falsy.functiontest(x): number{if(x)return10;}
  4. check if control flow falls through cases in switch statement (disabled by default, can be enabled via noFallthroughCasesInSwitch compiler option). Note that cases without statements are not reported.

    switch(x){// OKcase1: case2: return1;}switch(x){case1:
    if(y)return1;case2: return2;}

If these errors are showing up in your code and you still think that scenario when they appear is legitimate you can suppress errors with compiler options.

--module is not allowed alongside --outFile unless --module is specified as one of amd or system.

Previously specifying both while using modules would result in an empty out file and no error.

Changes to DOM API's in the standard library

  • ImageData.data is now of type Uint8ClampedArray instead of number[]. See #949 for more details.
  • HTMLSelectElement .options is now of type HTMLCollection instead of HTMLSelectElement. See #1558 for more details.
  • HTMLTableElement.createCaption, HTMLTableElement.createTBody, HTMLTableElement.createTFoot, HTMLTableElement.createTHead, HTMLTableElement.insertRow, HTMLTableSectionElement.insertRow, and HTMLTableElement.insertRow now return HTMLTableRowElement instead of HTMLElement. See #3583 for more details.
  • HTMLTableRowElement.insertCell now return HTMLTableCellElement instead of HTMLElement. See #3583 for more details.
  • IDBObjectStore.createIndex and IDBDatabase.createIndex second argument is now of type IDBObjectStoreParameters instead of any. See #5932 for more details.
  • DataTransferItemList.Item returns type now is DataTransferItem instead of File. See #6106 for more details.
  • Window.open return type now is Window instead of any. See #6418 for more details.
  • WeakMap.clear as removed. See #6500 for more details.

Disallow this accessing before super-call

ES6 disallows accessing this in a constructor declaration.

For example:

classB{constructor(that?: any){}}classCextendsB{constructor(){super(this);// error;}}classDextendsB{private_prop1: number;constructor(){this._prop1=10;// errorsuper();}}

TypeScript 1.7

For full list of breaking changes see the breaking change issues.

Changes in inferring the type from this

In a class, the type of the value this will be inferred to the this type. This means subsequent assignments from values the original type can fail.

Example:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest=this;if(Math.rand()<0.5){theVeryBest=opponent;// error}returntheVeryBest}}

Recommendations:

Add a type annotation:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest: Fighter=this;if(Math.rand()<0.5){theVeryBest=opponent;// no error}returntheVeryBest}}

Automatic semicolon insertion after class member modifiers

The keywords abstract, public, protected and private are FutureReservedWords in ECMAScript 3 and are subject to automatic semicolon insertion. Previously, TypeScript did not insert semicolons when these keywords were on their own line. Now that this is fixed, abstract class D no longer correctly extends C in the following example, and instead declares a concrete method m and an additional property named abstract.

Note that async and declare already correctly did ASI.

Example:

abstractclassC{abstractm(): number;}abstractclassDextendsC{abstractm(): number;}

Recommendations:

Remove line breaks after keywords when defining class members. In general, avoid relying on automatic semicolon insertion.

TypeScript 1.6

For full list of breaking changes see the breaking change issues.

Strict object literal assignment checking

It is an error to specify properties in an object literal that were not specified on the target type, when assigned to a variable or passed for a parameter of a non-empty target type.

This new strictness can be disabled with the --suppressExcessPropertyErrors compiler option.

Example:

varx: {foo: number};x={foo: 1,baz: 2};// Error, excess property `baz`vary: {foo: number,bar?: number};y={foo: 1,baz: 2};// Error, excess or misspelled property `baz`

Recommendations:

To avoid the error, there are few remedies based on the situation you are looking into:

If the target type accepts additional properties, add an indexer:

varx: {foo: number,[x: string]: any};x={foo: 1,baz: 2};// OK, `baz` matched by index signature

If the source types are a set of related types, explicitly specify them using union types instead of just specifying the base type.

letanimalList: (Dog|Cat|Turkey)[]=[// use union type instead of Animal{name: "Milo",meow: true},{name: "Pepper",bark: true},{name: "koko",gobble: true}];

Otherwise, explicitly cast to the target type to avoid the warning message:

interfaceFoo{foo: number;}interfaceFooBar{foo: number;bar: number;}vary: Foo;y=<FooBar>{foo: 1,bar: 2};

CommonJS module resolution no longer assumes paths are relative

Previously, for the files one.ts and two.ts, an import of "one" in two.ts would resolve to one.ts if they resided in the same directory.

In TypeScript 1.6, "one" is no longer equivalent to "./one" when compiling with CommonJS. Instead, it is searched as relative to an appropriate node_modules folder as would be resolved by runtimes such as Node.js. For details, see the issue that describes the resolution algorithm.

Example:

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"one";

Recommendations:

Fix any non-relative import names that were unintended (strongly suggested).

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"./one";

Set the --moduleResolution compiler option to classic.

Function and class default export declarations can no longer merge with entities intersecting in their meaning

Declaring an entity with the same name and in the same space as a default export declaration is now an error; for example,

exportdefaultfunctionfoo(){}namespacefoo{varx=100;}

and

exportdefaultclassFoo{a: number;}interfaceFoo{b: string;}

both cause an error.

However, in the following example, merging is allowed because the namespace does does not have a meaning in the value space:

exportdefaultclassFoo{}namespaceFoo{}

Recommendations:

Declare a local for your default export and use a separate export default statement as so:

classFoo{a: number;}interfacefoo{b: string;}exportdefaultFoo;

For more details see the originating issue.

Module bodies are parsed in strict mode

In accordance with the ES6 spec, module bodies are now parsed in strict mode. module bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

Changes to DOM API's in the standard library

  • MessageEvent and ProgressEvent constructors now expect arguments; see issue #4295 for more details.
  • ImageData constructor now expects arguments; see issue #4220 for more details.
  • File constructor now expects arguments; see issue #3999 for more details.

System module output uses bulk exports

The compiler uses the new bulk-export variation of the _export function in the System module format that takes any object containing key value pairs (optionally an entire module object for export *) as arguments instead of key, value.

The module loader needs to be updated to v0.17.1 or higher.

.js content of npm package is moved from 'bin' to 'lib' folder

Entry point of TypeScript npm package was moved from bin to lib to unblock scenarios when 'node_modules/typescript/bin/typescript.js' is served from IIS (by default bin is in the list of hidden segments so IIS will block access to this folder).

TypeScript npm package does not install globally by default

TypeScript 1.6 removes the preferGlobal flag from package.json. If you rely on this behaviour please use npm install -g typescript.

Decorators are checked as call expressions

Starting with 1.6, decorators type checking is more accurate; the compiler will checks a decorator expression as a call expression with the decorated entity as a parameter. This can cause error to be reported that were not in previous releases.

TypeScript 1.5

For full list of breaking changes see the breaking change issues.

Referencing arguments in arrow functions is not allowed

This is an alignment with the ES6 semantics of arrow functions. Previously arguments within an arrow function would bind to the arrow function arguments. As per ES6 spec draft 9.2.12, arrow functions do not have an arguments objects. In TypeScript 1.5, the use of arguments object in arrow functions will be flagged as an error to ensure your code ports to ES6 with no change in semantics.

Example:

functionf(){return()=>arguments;// Error: The 'arguments' object cannot be referenced in an arrow function. }

Recommendations:

// 1. Use named rest args functionf(){return(...args)=>{args;}}// 2. Use function expressions insteadfunctionf(){returnfunction(){arguments;}}

Enum reference in-lining changes

For regular enums, pre 1.5, the compiler only inline constant members, and a member was only constant if its initializer was a literal. That resulted in inconsistent behavior depending on whether the enum value is initalized with a literal or an expression. Starting with Typescript 1.5 all non-const enum members are not inlined.

Example:

varx=E.a;// previously inlined as "var x = 1; /*E.a*/"enumE{a=1}

Recommendation: Add the const modifier to the enum declaration to ensure it is consistently inlined at all consumption sites.

For more details see issue #2183.

Contextual type flows through super and parenthesized expressions

Prior to this release, contextual types did not flow through parenthesized expressions. This has forced explicit type casts, especially in cases where parentheses are required to make an expression parse.

In the examples below, m will have a contextual type, where previously it did not.

varx: SomeType=(n)=>((m)=>q);vary: SomeType=t ? (m=>m.length) : undefined;classCextendsCBase<string>{constructor(){super({method(m){returnm.length;}});}}

See issues #1425 and #920 for more details.

DOM interface changes

TypeScript 1.5 refreshes the DOM types in lib.d.ts. This is the first major refresh since TypeScript 1.0; many IE-specific definitions have been removed in favor of the standard DOM definitions, as well as adding missing types like Web Audio and touch events.

Workaround:

You can keep using older versions of the library with newer version of the compiler. You will need to include a local copy of a previous version in your project. Here is the last released version before this change (TypeScript 1.5-alpha).

Here is a list of changes:

  • Property selection is removed from type Document
  • Property clipboardData is removed from type Window
  • Removed interface MSEventAttachmentTarget
  • Properties onresize, disabled, uniqueID, removeNode, fireEvent, currentStyle, runtimeStyle are removed from type HTMLElement
  • Property url is removed from type Event
  • Properties execScript, navigate, item are removed from type Window
  • Properties documentMode, parentWindow, createEventObject are removed from type Document
  • Property parentWindow is removed from type HTMLDocument
  • Property setCapture does not exist anywhere now
  • Property releaseCapture does not exist anywhere now
  • Properties setAttribute, styleFloat, pixelLeft are removed from type CSSStyleDeclaration
  • Property selectorText is removed from type CSSRule
  • CSSStyleSheet.rules is of type CSSRuleList instead of MSCSSRuleList
  • documentElement is of type Element instead of HTMLElement
  • Event has a new required property returnValue
  • Node has a new required property baseURI
  • Element has a new required property classList
  • Location has a new required property origin
  • Properties MSPOINTER_TYPE_MOUSE, MSPOINTER_TYPE_TOUCH are removed from type MSPointerEvent
  • CSSStyleRule has a new required property readonly
  • Property execUnsafeLocalFunction is removed from type MSApp
  • Global method toStaticHTML is removed
  • HTMLCanvasElement.getContext now returns CanvasRenderingContext2D | WebGLRenderingContex
  • Removed extension types Dataview, Weakmap, Map, Set
  • XMLHttpRequest.send has two overloads send(data?: Document): void; and send(data?: String): void;
  • window.orientation is of type string instead of number
  • IE-specific attachEvent and detachEvent are removed from Window

Here is a list of libraries that are partly or entirely replaced by the added DOM types:

  • DefinitelyTyped/auth0/auth0.d.ts
  • DefinitelyTyped/gamepad/gamepad.d.ts
  • DefinitelyTyped/interactjs/interact.d.ts
  • DefinitelyTyped/webaudioapi/waa.d.ts
  • DefinitelyTyped/webcrypto/WebCrypto.d.ts

For more details, please see the full change.

Class bodies are parsed in strict mode

In accordance with the ES6 spec, class bodies are now parsed in strict mode. Class bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

TypeScript 1.4

For full list of breaking changes see the breaking change issues.

See issue #868 for more details about breaking changes related to Union Types

Multiple Best Common Type Candidates

Given multiple viable candidates from a Best Common Type computation we now choose an item (depending on the compiler's implementation) rather than the first item.

vara: {x: number;y?: number};varb: {x: number;z?: number};// was { x: number; z?: number; }[]// now { x: number; y?: number; }[]varbs=[b,a];

This can happen in a variety of circumstances. A shared set of required properties and a disjoint set of other properties (optional or otherwise), empty types, compatible signature types (including generic and non-generic signatures when type parameters are stamped out with any).

Recommendation Provide a type annotation if you need a specific type to be chosen

varbs: {x: number;y?: number;z?: number}[]=[b,a];

Generic Type Inference

Using different types for multiple arguments of type T is now an error, even with constraints involved:

declarefunctionfoo<T>(x: T,y:T): T;varr=foo(1,"");// r used to be {}, now this is an error

With constraints:

interfaceAnimal{x}interfaceGiraffeextendsAnimal{y}interfaceElephantextendsAnimal{z}functionf<TextendsAnimal>(x: T,y: T): T{returnundefined;}varg: Giraffe;vare: Elephant;f(g,e);

See https://github.com/Microsoft/TypeScript/pull/824#discussion_r18665727 for explanation.

Recommendations Specify an explicit type parameter if the mismatch was intentional:

varr=foo<{}>(1,"");// Emulates 1.0 behaviorvarr=foo<string|number>(1,"");// Most usefulvarr=foo<any>(1,"");// Easiestf<Animal>(g,e);

or rewrite the function definition to specify that mismatches are OK:

declarefunctionfoo<T,U>(x: T,y:U): T|U;functionf<TextendsAnimal,UextendsAnimal>(x: T,y: U): T|U{returnundefined;}

Generic Rest Parameters

You cannot use heterogeneous argument types anymore:

functionmakeArray<T>(...items: T[]): T[]{returnitems;}varr=makeArray(1,"");// used to return {}[], now an error

Likewise for new Array(...)

Recommendations Declare a back-compat signature if the 1.0 behavior was desired:

functionmakeArray<T>(...items: T[]): T[];functionmakeArray(...items: {}[]): {}[];functionmakeArray<T>(...items: T[]): T[]{returnitems;}

Overload Resolution with Type Argument Inference

varf10: <T>(x: T,b: ()=>(a: T)=>void,y: T)=>T;varr9=f10('',()=>(a=>a.foo),1);// r9 was any, now this is an error

Recommendations Manually specify a type parameter

varr9=f10<any>('',()=>(a=>a.foo),1);

Strict Mode Parsing for Class Declarations and Class Expressions

ECMAScript 2015 Language Specification (ECMA-262 6th Edition) specifies that ClassDeclaration and ClassExpression are strict mode productions. Thus, additional restrictions will be applied when parsing a class declaration or class expression.

Examples:

classimplements{}// Invalid: implements is a reserved word in strict modeclassC{foo(arguments: any){// Invalid: "arguments" is not allow as a function argumentvareval=10;// Invalid: "eval" is not allowed as the left-hand-side expressionarguments=[];// Invalid: arguments object is immutable}}

For complete list of strict mode restrictions, please see Annex C - The Strict Mode of ECMAScript of ECMA-262 6th Edition.

TypeScript 1.1

For full list of breaking changes see the breaking change issues.

Working with null and undefined in ways that are observably incorrect is now an error

Examples:

varResultIsNumber17=+(null+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.varResultIsNumber18=+(null+null);// Operator '+' cannot be applied to types 'null' and 'null'.varResultIsNumber19=+(undefined+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.

Similarly, using null and undefined directly as objects that have methods now is an error

Examples:

null.toBAZ();undefined.toBAZ();

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Daniel Rosenwasser edited this page Aug 16, 2016 · 68 revisions

These changes list where implementation differs between versions as the spec and compiler are simplified and inconsistencies are corrected.

For breaking changes to the compiler/services API, please check the API Breaking Changes page.

TypeScript 2.0

For full list of breaking changes see the breaking change issues.

No type narrowing for captured variables in functions and class expressions

Type narrowing does not cross function and class expressions, as well as lambda expressions.

Example

varx: number|string;if(typeofx==="number"){functioninner(): number{returnx;// Error, type of x is not narrowed, c is number | string}vary: number=x;// OK, x is number}

In the previous pattern the compiler can not tell when the callback will execute. Consider:

varx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}x=5;

It is wrong to assume x is a string when x.charAt() is called, as indeed it isn't.

Recommendation

Use constants instead:

constx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}

Generic type parameters are now narrowed

Example

functiong<T>(obj: T){vart: T;if(objinstanceofRegExp){t=obj;// RegExp is not assignable to T}}

Recommendation Either declare your locals to be a specific type and not the generic type parameter, or use a type assertion.

Getters with no setters are automatically inferred to be readonly properties

Example

classC{getx(){return0;}}varc=newC();c.x=1;// Error Left-hand side is a readonly property

Recommendation

Define a setter for do not write to the property.

Function declarations not allowed in blocks in strict mode

This is already a run-time error under strict mode. Starting with TypeScript 2.0, it will be flagged as a compile-time error as well.

Example

if(true){functionfoo(){}}export=foo;

Recommendation

Use function expressions instead:

if(true){constfoo=function(){}}

TemplateStringsArray is now immutable

ES2015 tagged templates always pass their tag an immutable array-like object that has a property called raw (which is also immutable). TypeScript names this object the TemplateStringsArray.

Conveniently, TemplateStringsArray was assignable to an Array<string>, so it's possible users took advantage of this to use a shorter type for their tag parameters:

functionmyTemplateTag(strs: string[]){// ...}

However, in TypeScript 2.0, the language now supports the readonly modifier and can express that these objects are immutable. As a result, TemplateStringsArray has also been made immutable, and is no longer assignable to string[].

Recommendation

Use TemplateStringsArray explicitly (or use ReadonlyArray<string>).

TypeScript 1.8

For full list of breaking changes see the breaking change issues.

Modules are now emitted with a "use strict"; prologue

Modules were always parsed in strict mode as per ES6, but for non-ES6 targets this was not respected in the generated code. Starting with TypeScript 1.8, emitted modules are always in strict mode. This shouldn't have any visible changes in most code as TS considers most strict mode errors as errors at compile time, but it means that some things which used to silently fail at runtime in your TS code, like assigning to NaN, will now loudly fail. You can reference the MDN Article on strict mode for a detailed list of the differences between strict mode and non-strict mode.

To disable this behavior, pass --noImplicitUseStrict on the command line or set it in your tsconfig.json file.

Exporting non-local names from a module

In accordance with the ES6/ES2015 spec, it is an error to export a non-local name from a module.

Example

export{Promise};// Error

Recommendation

Use a local variable declaration to capture the global name before exporting it.

constlocalPromise=Promise;export{localPromiseasPromise};

Reachability checks are enabled by default

In TypeScript 1.8 we've added a set of reachability checks to prevent certain categories of errors. Specifically

  1. check if code is reachable (enabled by default, can be disabled via allowUnreachableCode compiler option)

    functiontest1(){return1;return2;// error here}functiontest2(x){if(x){return1;}else{thrownewError("NYI")}vary=1;// error here}
  2. check if label is unused (enabled by default, can be disabled via allowUnusedLabels compiler option)

    l: // error will be reported - label `l` is unusedwhile(true){}(x)=>{x:x}// error will be reported - label `x` is unused
  3. check if all code paths in function with return type annotation return some value (disabled by default, can be enabled via noImplicitReturns compiler option)

    // error will be reported since function does not return anything explicitly when `x` is falsy.functiontest(x): number{if(x)return10;}
  4. check if control flow falls through cases in switch statement (disabled by default, can be enabled via noFallthroughCasesInSwitch compiler option). Note that cases without statements are not reported.

    switch(x){// OKcase1: case2: return1;}switch(x){case1:
    if(y)return1;case2: return2;}

If these errors are showing up in your code and you still think that scenario when they appear is legitimate you can suppress errors with compiler options.

--module is not allowed alongside --outFile unless --module is specified as one of amd or system.

Previously specifying both while using modules would result in an empty out file and no error.

Changes to DOM API's in the standard library

  • ImageData.data is now of type Uint8ClampedArray instead of number[]. See #949 for more details.
  • HTMLSelectElement .options is now of type HTMLCollection instead of HTMLSelectElement. See #1558 for more details.
  • HTMLTableElement.createCaption, HTMLTableElement.createTBody, HTMLTableElement.createTFoot, HTMLTableElement.createTHead, HTMLTableElement.insertRow, HTMLTableSectionElement.insertRow, and HTMLTableElement.insertRow now return HTMLTableRowElement instead of HTMLElement. See #3583 for more details.
  • HTMLTableRowElement.insertCell now return HTMLTableCellElement instead of HTMLElement. See #3583 for more details.
  • IDBObjectStore.createIndex and IDBDatabase.createIndex second argument is now of type IDBObjectStoreParameters instead of any. See #5932 for more details.
  • DataTransferItemList.Item returns type now is DataTransferItem instead of File. See #6106 for more details.
  • Window.open return type now is Window instead of any. See #6418 for more details.
  • WeakMap.clear as removed. See #6500 for more details.

Disallow this accessing before super-call

ES6 disallows accessing this in a constructor declaration.

For example:

classB{constructor(that?: any){}}classCextendsB{constructor(){super(this);// error;}}classDextendsB{private_prop1: number;constructor(){this._prop1=10;// errorsuper();}}

TypeScript 1.7

For full list of breaking changes see the breaking change issues.

Changes in inferring the type from this

In a class, the type of the value this will be inferred to the this type. This means subsequent assignments from values the original type can fail.

Example:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest=this;if(Math.rand()<0.5){theVeryBest=opponent;// error}returntheVeryBest}}

Recommendations:

Add a type annotation:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest: Fighter=this;if(Math.rand()<0.5){theVeryBest=opponent;// no error}returntheVeryBest}}

Automatic semicolon insertion after class member modifiers

The keywords abstract, public, protected and private are FutureReservedWords in ECMAScript 3 and are subject to automatic semicolon insertion. Previously, TypeScript did not insert semicolons when these keywords were on their own line. Now that this is fixed, abstract class D no longer correctly extends C in the following example, and instead declares a concrete method m and an additional property named abstract.

Note that async and declare already correctly did ASI.

Example:

abstractclassC{abstractm(): number;}abstractclassDextendsC{abstractm(): number;}

Recommendations:

Remove line breaks after keywords when defining class members. In general, avoid relying on automatic semicolon insertion.

TypeScript 1.6

For full list of breaking changes see the breaking change issues.

Strict object literal assignment checking

It is an error to specify properties in an object literal that were not specified on the target type, when assigned to a variable or passed for a parameter of a non-empty target type.

This new strictness can be disabled with the --suppressExcessPropertyErrors compiler option.

Example:

varx: {foo: number};x={foo: 1,baz: 2};// Error, excess property `baz`vary: {foo: number,bar?: number};y={foo: 1,baz: 2};// Error, excess or misspelled property `baz`

Recommendations:

To avoid the error, there are few remedies based on the situation you are looking into:

If the target type accepts additional properties, add an indexer:

varx: {foo: number,[x: string]: any};x={foo: 1,baz: 2};// OK, `baz` matched by index signature

If the source types are a set of related types, explicitly specify them using union types instead of just specifying the base type.

letanimalList: (Dog|Cat|Turkey)[]=[// use union type instead of Animal{name: "Milo",meow: true},{name: "Pepper",bark: true},{name: "koko",gobble: true}];

Otherwise, explicitly cast to the target type to avoid the warning message:

interfaceFoo{foo: number;}interfaceFooBar{foo: number;bar: number;}vary: Foo;y=<FooBar>{foo: 1,bar: 2};

CommonJS module resolution no longer assumes paths are relative

Previously, for the files one.ts and two.ts, an import of "one" in two.ts would resolve to one.ts if they resided in the same directory.

In TypeScript 1.6, "one" is no longer equivalent to "./one" when compiling with CommonJS. Instead, it is searched as relative to an appropriate node_modules folder as would be resolved by runtimes such as Node.js. For details, see the issue that describes the resolution algorithm.

Example:

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"one";

Recommendations:

Fix any non-relative import names that were unintended (strongly suggested).

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"./one";

Set the --moduleResolution compiler option to classic.

Function and class default export declarations can no longer merge with entities intersecting in their meaning

Declaring an entity with the same name and in the same space as a default export declaration is now an error; for example,

exportdefaultfunctionfoo(){}namespacefoo{varx=100;}

and

exportdefaultclassFoo{a: number;}interfaceFoo{b: string;}

both cause an error.

However, in the following example, merging is allowed because the namespace does does not have a meaning in the value space:

exportdefaultclassFoo{}namespaceFoo{}

Recommendations:

Declare a local for your default export and use a separate export default statement as so:

classFoo{a: number;}interfacefoo{b: string;}exportdefaultFoo;

For more details see the originating issue.

Module bodies are parsed in strict mode

In accordance with the ES6 spec, module bodies are now parsed in strict mode. module bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

Changes to DOM API's in the standard library

  • MessageEvent and ProgressEvent constructors now expect arguments; see issue #4295 for more details.
  • ImageData constructor now expects arguments; see issue #4220 for more details.
  • File constructor now expects arguments; see issue #3999 for more details.

System module output uses bulk exports

The compiler uses the new bulk-export variation of the _export function in the System module format that takes any object containing key value pairs (optionally an entire module object for export *) as arguments instead of key, value.

The module loader needs to be updated to v0.17.1 or higher.

.js content of npm package is moved from 'bin' to 'lib' folder

Entry point of TypeScript npm package was moved from bin to lib to unblock scenarios when 'node_modules/typescript/bin/typescript.js' is served from IIS (by default bin is in the list of hidden segments so IIS will block access to this folder).

TypeScript npm package does not install globally by default

TypeScript 1.6 removes the preferGlobal flag from package.json. If you rely on this behaviour please use npm install -g typescript.

Decorators are checked as call expressions

Starting with 1.6, decorators type checking is more accurate; the compiler will checks a decorator expression as a call expression with the decorated entity as a parameter. This can cause error to be reported that were not in previous releases.

TypeScript 1.5

For full list of breaking changes see the breaking change issues.

Referencing arguments in arrow functions is not allowed

This is an alignment with the ES6 semantics of arrow functions. Previously arguments within an arrow function would bind to the arrow function arguments. As per ES6 spec draft 9.2.12, arrow functions do not have an arguments objects. In TypeScript 1.5, the use of arguments object in arrow functions will be flagged as an error to ensure your code ports to ES6 with no change in semantics.

Example:

functionf(){return()=>arguments;// Error: The 'arguments' object cannot be referenced in an arrow function. }

Recommendations:

// 1. Use named rest args functionf(){return(...args)=>{args;}}// 2. Use function expressions insteadfunctionf(){returnfunction(){arguments;}}

Enum reference in-lining changes

For regular enums, pre 1.5, the compiler only inline constant members, and a member was only constant if its initializer was a literal. That resulted in inconsistent behavior depending on whether the enum value is initalized with a literal or an expression. Starting with Typescript 1.5 all non-const enum members are not inlined.

Example:

varx=E.a;// previously inlined as "var x = 1; /*E.a*/"enumE{a=1}

Recommendation: Add the const modifier to the enum declaration to ensure it is consistently inlined at all consumption sites.

For more details see issue #2183.

Contextual type flows through super and parenthesized expressions

Prior to this release, contextual types did not flow through parenthesized expressions. This has forced explicit type casts, especially in cases where parentheses are required to make an expression parse.

In the examples below, m will have a contextual type, where previously it did not.

varx: SomeType=(n)=>((m)=>q);vary: SomeType=t ? (m=>m.length) : undefined;classCextendsCBase<string>{constructor(){super({method(m){returnm.length;}});}}

See issues #1425 and #920 for more details.

DOM interface changes

TypeScript 1.5 refreshes the DOM types in lib.d.ts. This is the first major refresh since TypeScript 1.0; many IE-specific definitions have been removed in favor of the standard DOM definitions, as well as adding missing types like Web Audio and touch events.

Workaround:

You can keep using older versions of the library with newer version of the compiler. You will need to include a local copy of a previous version in your project. Here is the last released version before this change (TypeScript 1.5-alpha).

Here is a list of changes:

  • Property selection is removed from type Document
  • Property clipboardData is removed from type Window
  • Removed interface MSEventAttachmentTarget
  • Properties onresize, disabled, uniqueID, removeNode, fireEvent, currentStyle, runtimeStyle are removed from type HTMLElement
  • Property url is removed from type Event
  • Properties execScript, navigate, item are removed from type Window
  • Properties documentMode, parentWindow, createEventObject are removed from type Document
  • Property parentWindow is removed from type HTMLDocument
  • Property setCapture does not exist anywhere now
  • Property releaseCapture does not exist anywhere now
  • Properties setAttribute, styleFloat, pixelLeft are removed from type CSSStyleDeclaration
  • Property selectorText is removed from type CSSRule
  • CSSStyleSheet.rules is of type CSSRuleList instead of MSCSSRuleList
  • documentElement is of type Element instead of HTMLElement
  • Event has a new required property returnValue
  • Node has a new required property baseURI
  • Element has a new required property classList
  • Location has a new required property origin
  • Properties MSPOINTER_TYPE_MOUSE, MSPOINTER_TYPE_TOUCH are removed from type MSPointerEvent
  • CSSStyleRule has a new required property readonly
  • Property execUnsafeLocalFunction is removed from type MSApp
  • Global method toStaticHTML is removed
  • HTMLCanvasElement.getContext now returns CanvasRenderingContext2D | WebGLRenderingContex
  • Removed extension types Dataview, Weakmap, Map, Set
  • XMLHttpRequest.send has two overloads send(data?: Document): void; and send(data?: String): void;
  • window.orientation is of type string instead of number
  • IE-specific attachEvent and detachEvent are removed from Window

Here is a list of libraries that are partly or entirely replaced by the added DOM types:

  • DefinitelyTyped/auth0/auth0.d.ts
  • DefinitelyTyped/gamepad/gamepad.d.ts
  • DefinitelyTyped/interactjs/interact.d.ts
  • DefinitelyTyped/webaudioapi/waa.d.ts
  • DefinitelyTyped/webcrypto/WebCrypto.d.ts

For more details, please see the full change.

Class bodies are parsed in strict mode

In accordance with the ES6 spec, class bodies are now parsed in strict mode. Class bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

TypeScript 1.4

For full list of breaking changes see the breaking change issues.

See issue #868 for more details about breaking changes related to Union Types

Multiple Best Common Type Candidates

Given multiple viable candidates from a Best Common Type computation we now choose an item (depending on the compiler's implementation) rather than the first item.

vara: {x: number;y?: number};varb: {x: number;z?: number};// was { x: number; z?: number; }[]// now { x: number; y?: number; }[]varbs=[b,a];

This can happen in a variety of circumstances. A shared set of required properties and a disjoint set of other properties (optional or otherwise), empty types, compatible signature types (including generic and non-generic signatures when type parameters are stamped out with any).

Recommendation Provide a type annotation if you need a specific type to be chosen

varbs: {x: number;y?: number;z?: number}[]=[b,a];

Generic Type Inference

Using different types for multiple arguments of type T is now an error, even with constraints involved:

declarefunctionfoo<T>(x: T,y:T): T;varr=foo(1,"");// r used to be {}, now this is an error

With constraints:

interfaceAnimal{x}interfaceGiraffeextendsAnimal{y}interfaceElephantextendsAnimal{z}functionf<TextendsAnimal>(x: T,y: T): T{returnundefined;}varg: Giraffe;vare: Elephant;f(g,e);

See https://github.com/Microsoft/TypeScript/pull/824#discussion_r18665727 for explanation.

Recommendations Specify an explicit type parameter if the mismatch was intentional:

varr=foo<{}>(1,"");// Emulates 1.0 behaviorvarr=foo<string|number>(1,"");// Most usefulvarr=foo<any>(1,"");// Easiestf<Animal>(g,e);

or rewrite the function definition to specify that mismatches are OK:

declarefunctionfoo<T,U>(x: T,y:U): T|U;functionf<TextendsAnimal,UextendsAnimal>(x: T,y: U): T|U{returnundefined;}

Generic Rest Parameters

You cannot use heterogeneous argument types anymore:

functionmakeArray<T>(...items: T[]): T[]{returnitems;}varr=makeArray(1,"");// used to return {}[], now an error

Likewise for new Array(...)

Recommendations Declare a back-compat signature if the 1.0 behavior was desired:

functionmakeArray<T>(...items: T[]): T[];functionmakeArray(...items: {}[]): {}[];functionmakeArray<T>(...items: T[]): T[]{returnitems;}

Overload Resolution with Type Argument Inference

varf10: <T>(x: T,b: ()=>(a: T)=>void,y: T)=>T;varr9=f10('',()=>(a=>a.foo),1);// r9 was any, now this is an error

Recommendations Manually specify a type parameter

varr9=f10<any>('',()=>(a=>a.foo),1);

Strict Mode Parsing for Class Declarations and Class Expressions

ECMAScript 2015 Language Specification (ECMA-262 6th Edition) specifies that ClassDeclaration and ClassExpression are strict mode productions. Thus, additional restrictions will be applied when parsing a class declaration or class expression.

Examples:

classimplements{}// Invalid: implements is a reserved word in strict modeclassC{foo(arguments: any){// Invalid: "arguments" is not allow as a function argumentvareval=10;// Invalid: "eval" is not allowed as the left-hand-side expressionarguments=[];// Invalid: arguments object is immutable}}

For complete list of strict mode restrictions, please see Annex C - The Strict Mode of ECMAScript of ECMA-262 6th Edition.

TypeScript 1.1

For full list of breaking changes see the breaking change issues.

Working with null and undefined in ways that are observably incorrect is now an error

Examples:

varResultIsNumber17=+(null+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.varResultIsNumber18=+(null+null);// Operator '+' cannot be applied to types 'null' and 'null'.varResultIsNumber19=+(undefined+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.

Similarly, using null and undefined directly as objects that have methods now is an error

Examples:

null.toBAZ();undefined.toBAZ();

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Daniel Rosenwasser edited this page Aug 16, 2016 · 68 revisions

These changes list where implementation differs between versions as the spec and compiler are simplified and inconsistencies are corrected.

For breaking changes to the compiler/services API, please check the API Breaking Changes page.

TypeScript 2.0

For full list of breaking changes see the breaking change issues.

No type narrowing for captured variables in functions and class expressions

Type narrowing does not cross function and class expressions, as well as lambda expressions.

Example

varx: number|string;if(typeofx==="number"){functioninner(): number{returnx;// Error, type of x is not narrowed, c is number | string}vary: number=x;// OK, x is number}

In the previous pattern the compiler can not tell when the callback will execute. Consider:

varx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}x=5;

It is wrong to assume x is a string when x.charAt() is called, as indeed it isn't.

Recommendation

Use constants instead:

constx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}

Generic type parameters are now narrowed

Example

functiong<T>(obj: T){vart: T;if(objinstanceofRegExp){t=obj;// RegExp is not assignable to T}}

Recommendation Either declare your locals to be a specific type and not the generic type parameter, or use a type assertion.

Getters with no setters are automatically inferred to be readonly properties

Example

classC{getx(){return0;}}varc=newC();c.x=1;// Error Left-hand side is a readonly property

Recommendation

Define a setter for do not write to the property.

Function declarations not allowed in blocks in strict mode

This is already a run-time error under strict mode. Starting with TypeScript 2.0, it will be flagged as a compile-time error as well.

Example

if(true){functionfoo(){}}export=foo;

Recommendation

Use function expressions instead:

if(true){constfoo=function(){}}

TemplateStringsArray is now immutable

ES2015 tagged templates always pass their tag an immutable array-like object that has a property called raw (which is also immutable). TypeScript names this object the TemplateStringsArray.

Conveniently, TemplateStringsArray was assignable to an Array<string>, so it's possible users took advantage of this to use a shorter type for their tag parameters:

functionmyTemplateTag(strs: string[]){// ...}

However, in TypeScript 2.0, the language now supports the readonly modifier and can express that these objects are immutable. As a result, TemplateStringsArray has also been made immutable, and is no longer assignable to string[].

Recommendation

Use TemplateStringsArray explicitly (or use ReadonlyArray<string>).

TypeScript 1.8

For full list of breaking changes see the breaking change issues.

Modules are now emitted with a "use strict"; prologue

Modules were always parsed in strict mode as per ES6, but for non-ES6 targets this was not respected in the generated code. Starting with TypeScript 1.8, emitted modules are always in strict mode. This shouldn't have any visible changes in most code as TS considers most strict mode errors as errors at compile time, but it means that some things which used to silently fail at runtime in your TS code, like assigning to NaN, will now loudly fail. You can reference the MDN Article on strict mode for a detailed list of the differences between strict mode and non-strict mode.

To disable this behavior, pass --noImplicitUseStrict on the command line or set it in your tsconfig.json file.

Exporting non-local names from a module

In accordance with the ES6/ES2015 spec, it is an error to export a non-local name from a module.

Example

export{Promise};// Error

Recommendation

Use a local variable declaration to capture the global name before exporting it.

constlocalPromise=Promise;export{localPromiseasPromise};

Reachability checks are enabled by default

In TypeScript 1.8 we've added a set of reachability checks to prevent certain categories of errors. Specifically

  1. check if code is reachable (enabled by default, can be disabled via allowUnreachableCode compiler option)

    functiontest1(){return1;return2;// error here}functiontest2(x){if(x){return1;}else{thrownewError("NYI")}vary=1;// error here}
  2. check if label is unused (enabled by default, can be disabled via allowUnusedLabels compiler option)

    l: // error will be reported - label `l` is unusedwhile(true){}(x)=>{x:x}// error will be reported - label `x` is unused
  3. check if all code paths in function with return type annotation return some value (disabled by default, can be enabled via noImplicitReturns compiler option)

    // error will be reported since function does not return anything explicitly when `x` is falsy.functiontest(x): number{if(x)return10;}
  4. check if control flow falls through cases in switch statement (disabled by default, can be enabled via noFallthroughCasesInSwitch compiler option). Note that cases without statements are not reported.

    switch(x){// OKcase1: case2: return1;}switch(x){case1:
    if(y)return1;case2: return2;}

If these errors are showing up in your code and you still think that scenario when they appear is legitimate you can suppress errors with compiler options.

--module is not allowed alongside --outFile unless --module is specified as one of amd or system.

Previously specifying both while using modules would result in an empty out file and no error.

Changes to DOM API's in the standard library

  • ImageData.data is now of type Uint8ClampedArray instead of number[]. See #949 for more details.
  • HTMLSelectElement .options is now of type HTMLCollection instead of HTMLSelectElement. See #1558 for more details.
  • HTMLTableElement.createCaption, HTMLTableElement.createTBody, HTMLTableElement.createTFoot, HTMLTableElement.createTHead, HTMLTableElement.insertRow, HTMLTableSectionElement.insertRow, and HTMLTableElement.insertRow now return HTMLTableRowElement instead of HTMLElement. See #3583 for more details.
  • HTMLTableRowElement.insertCell now return HTMLTableCellElement instead of HTMLElement. See #3583 for more details.
  • IDBObjectStore.createIndex and IDBDatabase.createIndex second argument is now of type IDBObjectStoreParameters instead of any. See #5932 for more details.
  • DataTransferItemList.Item returns type now is DataTransferItem instead of File. See #6106 for more details.
  • Window.open return type now is Window instead of any. See #6418 for more details.
  • WeakMap.clear as removed. See #6500 for more details.

Disallow this accessing before super-call

ES6 disallows accessing this in a constructor declaration.

For example:

classB{constructor(that?: any){}}classCextendsB{constructor(){super(this);// error;}}classDextendsB{private_prop1: number;constructor(){this._prop1=10;// errorsuper();}}

TypeScript 1.7

For full list of breaking changes see the breaking change issues.

Changes in inferring the type from this

In a class, the type of the value this will be inferred to the this type. This means subsequent assignments from values the original type can fail.

Example:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest=this;if(Math.rand()<0.5){theVeryBest=opponent;// error}returntheVeryBest}}

Recommendations:

Add a type annotation:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest: Fighter=this;if(Math.rand()<0.5){theVeryBest=opponent;// no error}returntheVeryBest}}

Automatic semicolon insertion after class member modifiers

The keywords abstract, public, protected and private are FutureReservedWords in ECMAScript 3 and are subject to automatic semicolon insertion. Previously, TypeScript did not insert semicolons when these keywords were on their own line. Now that this is fixed, abstract class D no longer correctly extends C in the following example, and instead declares a concrete method m and an additional property named abstract.

Note that async and declare already correctly did ASI.

Example:

abstractclassC{abstractm(): number;}abstractclassDextendsC{abstractm(): number;}

Recommendations:

Remove line breaks after keywords when defining class members. In general, avoid relying on automatic semicolon insertion.

TypeScript 1.6

For full list of breaking changes see the breaking change issues.

Strict object literal assignment checking

It is an error to specify properties in an object literal that were not specified on the target type, when assigned to a variable or passed for a parameter of a non-empty target type.

This new strictness can be disabled with the --suppressExcessPropertyErrors compiler option.

Example:

varx: {foo: number};x={foo: 1,baz: 2};// Error, excess property `baz`vary: {foo: number,bar?: number};y={foo: 1,baz: 2};// Error, excess or misspelled property `baz`

Recommendations:

To avoid the error, there are few remedies based on the situation you are looking into:

If the target type accepts additional properties, add an indexer:

varx: {foo: number,[x: string]: any};x={foo: 1,baz: 2};// OK, `baz` matched by index signature

If the source types are a set of related types, explicitly specify them using union types instead of just specifying the base type.

letanimalList: (Dog|Cat|Turkey)[]=[// use union type instead of Animal{name: "Milo",meow: true},{name: "Pepper",bark: true},{name: "koko",gobble: true}];

Otherwise, explicitly cast to the target type to avoid the warning message:

interfaceFoo{foo: number;}interfaceFooBar{foo: number;bar: number;}vary: Foo;y=<FooBar>{foo: 1,bar: 2};

CommonJS module resolution no longer assumes paths are relative

Previously, for the files one.ts and two.ts, an import of "one" in two.ts would resolve to one.ts if they resided in the same directory.

In TypeScript 1.6, "one" is no longer equivalent to "./one" when compiling with CommonJS. Instead, it is searched as relative to an appropriate node_modules folder as would be resolved by runtimes such as Node.js. For details, see the issue that describes the resolution algorithm.

Example:

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"one";

Recommendations:

Fix any non-relative import names that were unintended (strongly suggested).

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"./one";

Set the --moduleResolution compiler option to classic.

Function and class default export declarations can no longer merge with entities intersecting in their meaning

Declaring an entity with the same name and in the same space as a default export declaration is now an error; for example,

exportdefaultfunctionfoo(){}namespacefoo{varx=100;}

and

exportdefaultclassFoo{a: number;}interfaceFoo{b: string;}

both cause an error.

However, in the following example, merging is allowed because the namespace does does not have a meaning in the value space:

exportdefaultclassFoo{}namespaceFoo{}

Recommendations:

Declare a local for your default export and use a separate export default statement as so:

classFoo{a: number;}interfacefoo{b: string;}exportdefaultFoo;

For more details see the originating issue.

Module bodies are parsed in strict mode

In accordance with the ES6 spec, module bodies are now parsed in strict mode. module bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

Changes to DOM API's in the standard library

  • MessageEvent and ProgressEvent constructors now expect arguments; see issue #4295 for more details.
  • ImageData constructor now expects arguments; see issue #4220 for more details.
  • File constructor now expects arguments; see issue #3999 for more details.

System module output uses bulk exports

The compiler uses the new bulk-export variation of the _export function in the System module format that takes any object containing key value pairs (optionally an entire module object for export *) as arguments instead of key, value.

The module loader needs to be updated to v0.17.1 or higher.

.js content of npm package is moved from 'bin' to 'lib' folder

Entry point of TypeScript npm package was moved from bin to lib to unblock scenarios when 'node_modules/typescript/bin/typescript.js' is served from IIS (by default bin is in the list of hidden segments so IIS will block access to this folder).

TypeScript npm package does not install globally by default

TypeScript 1.6 removes the preferGlobal flag from package.json. If you rely on this behaviour please use npm install -g typescript.

Decorators are checked as call expressions

Starting with 1.6, decorators type checking is more accurate; the compiler will checks a decorator expression as a call expression with the decorated entity as a parameter. This can cause error to be reported that were not in previous releases.

TypeScript 1.5

For full list of breaking changes see the breaking change issues.

Referencing arguments in arrow functions is not allowed

This is an alignment with the ES6 semantics of arrow functions. Previously arguments within an arrow function would bind to the arrow function arguments. As per ES6 spec draft 9.2.12, arrow functions do not have an arguments objects. In TypeScript 1.5, the use of arguments object in arrow functions will be flagged as an error to ensure your code ports to ES6 with no change in semantics.

Example:

functionf(){return()=>arguments;// Error: The 'arguments' object cannot be referenced in an arrow function. }

Recommendations:

// 1. Use named rest args functionf(){return(...args)=>{args;}}// 2. Use function expressions insteadfunctionf(){returnfunction(){arguments;}}

Enum reference in-lining changes

For regular enums, pre 1.5, the compiler only inline constant members, and a member was only constant if its initializer was a literal. That resulted in inconsistent behavior depending on whether the enum value is initalized with a literal or an expression. Starting with Typescript 1.5 all non-const enum members are not inlined.

Example:

varx=E.a;// previously inlined as "var x = 1; /*E.a*/"enumE{a=1}

Recommendation: Add the const modifier to the enum declaration to ensure it is consistently inlined at all consumption sites.

For more details see issue #2183.

Contextual type flows through super and parenthesized expressions

Prior to this release, contextual types did not flow through parenthesized expressions. This has forced explicit type casts, especially in cases where parentheses are required to make an expression parse.

In the examples below, m will have a contextual type, where previously it did not.

varx: SomeType=(n)=>((m)=>q);vary: SomeType=t ? (m=>m.length) : undefined;classCextendsCBase<string>{constructor(){super({method(m){returnm.length;}});}}

See issues #1425 and #920 for more details.

DOM interface changes

TypeScript 1.5 refreshes the DOM types in lib.d.ts. This is the first major refresh since TypeScript 1.0; many IE-specific definitions have been removed in favor of the standard DOM definitions, as well as adding missing types like Web Audio and touch events.

Workaround:

You can keep using older versions of the library with newer version of the compiler. You will need to include a local copy of a previous version in your project. Here is the last released version before this change (TypeScript 1.5-alpha).

Here is a list of changes:

  • Property selection is removed from type Document
  • Property clipboardData is removed from type Window
  • Removed interface MSEventAttachmentTarget
  • Properties onresize, disabled, uniqueID, removeNode, fireEvent, currentStyle, runtimeStyle are removed from type HTMLElement
  • Property url is removed from type Event
  • Properties execScript, navigate, item are removed from type Window
  • Properties documentMode, parentWindow, createEventObject are removed from type Document
  • Property parentWindow is removed from type HTMLDocument
  • Property setCapture does not exist anywhere now
  • Property releaseCapture does not exist anywhere now
  • Properties setAttribute, styleFloat, pixelLeft are removed from type CSSStyleDeclaration
  • Property selectorText is removed from type CSSRule
  • CSSStyleSheet.rules is of type CSSRuleList instead of MSCSSRuleList
  • documentElement is of type Element instead of HTMLElement
  • Event has a new required property returnValue
  • Node has a new required property baseURI
  • Element has a new required property classList
  • Location has a new required property origin
  • Properties MSPOINTER_TYPE_MOUSE, MSPOINTER_TYPE_TOUCH are removed from type MSPointerEvent
  • CSSStyleRule has a new required property readonly
  • Property execUnsafeLocalFunction is removed from type MSApp
  • Global method toStaticHTML is removed
  • HTMLCanvasElement.getContext now returns CanvasRenderingContext2D | WebGLRenderingContex
  • Removed extension types Dataview, Weakmap, Map, Set
  • XMLHttpRequest.send has two overloads send(data?: Document): void; and send(data?: String): void;
  • window.orientation is of type string instead of number
  • IE-specific attachEvent and detachEvent are removed from Window

Here is a list of libraries that are partly or entirely replaced by the added DOM types:

  • DefinitelyTyped/auth0/auth0.d.ts
  • DefinitelyTyped/gamepad/gamepad.d.ts
  • DefinitelyTyped/interactjs/interact.d.ts
  • DefinitelyTyped/webaudioapi/waa.d.ts
  • DefinitelyTyped/webcrypto/WebCrypto.d.ts

For more details, please see the full change.

Class bodies are parsed in strict mode

In accordance with the ES6 spec, class bodies are now parsed in strict mode. Class bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

TypeScript 1.4

For full list of breaking changes see the breaking change issues.

See issue #868 for more details about breaking changes related to Union Types

Multiple Best Common Type Candidates

Given multiple viable candidates from a Best Common Type computation we now choose an item (depending on the compiler's implementation) rather than the first item.

vara: {x: number;y?: number};varb: {x: number;z?: number};// was { x: number; z?: number; }[]// now { x: number; y?: number; }[]varbs=[b,a];

This can happen in a variety of circumstances. A shared set of required properties and a disjoint set of other properties (optional or otherwise), empty types, compatible signature types (including generic and non-generic signatures when type parameters are stamped out with any).

Recommendation Provide a type annotation if you need a specific type to be chosen

varbs: {x: number;y?: number;z?: number}[]=[b,a];

Generic Type Inference

Using different types for multiple arguments of type T is now an error, even with constraints involved:

declarefunctionfoo<T>(x: T,y:T): T;varr=foo(1,"");// r used to be {}, now this is an error

With constraints:

interfaceAnimal{x}interfaceGiraffeextendsAnimal{y}interfaceElephantextendsAnimal{z}functionf<TextendsAnimal>(x: T,y: T): T{returnundefined;}varg: Giraffe;vare: Elephant;f(g,e);

See https://github.com/Microsoft/TypeScript/pull/824#discussion_r18665727 for explanation.

Recommendations Specify an explicit type parameter if the mismatch was intentional:

varr=foo<{}>(1,"");// Emulates 1.0 behaviorvarr=foo<string|number>(1,"");// Most usefulvarr=foo<any>(1,"");// Easiestf<Animal>(g,e);

or rewrite the function definition to specify that mismatches are OK:

declarefunctionfoo<T,U>(x: T,y:U): T|U;functionf<TextendsAnimal,UextendsAnimal>(x: T,y: U): T|U{returnundefined;}

Generic Rest Parameters

You cannot use heterogeneous argument types anymore:

functionmakeArray<T>(...items: T[]): T[]{returnitems;}varr=makeArray(1,"");// used to return {}[], now an error

Likewise for new Array(...)

Recommendations Declare a back-compat signature if the 1.0 behavior was desired:

functionmakeArray<T>(...items: T[]): T[];functionmakeArray(...items: {}[]): {}[];functionmakeArray<T>(...items: T[]): T[]{returnitems;}

Overload Resolution with Type Argument Inference

varf10: <T>(x: T,b: ()=>(a: T)=>void,y: T)=>T;varr9=f10('',()=>(a=>a.foo),1);// r9 was any, now this is an error

Recommendations Manually specify a type parameter

varr9=f10<any>('',()=>(a=>a.foo),1);

Strict Mode Parsing for Class Declarations and Class Expressions

ECMAScript 2015 Language Specification (ECMA-262 6th Edition) specifies that ClassDeclaration and ClassExpression are strict mode productions. Thus, additional restrictions will be applied when parsing a class declaration or class expression.

Examples:

classimplements{}// Invalid: implements is a reserved word in strict modeclassC{foo(arguments: any){// Invalid: "arguments" is not allow as a function argumentvareval=10;// Invalid: "eval" is not allowed as the left-hand-side expressionarguments=[];// Invalid: arguments object is immutable}}

For complete list of strict mode restrictions, please see Annex C - The Strict Mode of ECMAScript of ECMA-262 6th Edition.

TypeScript 1.1

For full list of breaking changes see the breaking change issues.

Working with null and undefined in ways that are observably incorrect is now an error

Examples:

varResultIsNumber17=+(null+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.varResultIsNumber18=+(null+null);// Operator '+' cannot be applied to types 'null' and 'null'.varResultIsNumber19=+(undefined+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.

Similarly, using null and undefined directly as objects that have methods now is an error

Examples:

null.toBAZ();undefined.toBAZ();

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Daniel Rosenwasser edited this page Aug 16, 2016 · 68 revisions

These changes list where implementation differs between versions as the spec and compiler are simplified and inconsistencies are corrected.

For breaking changes to the compiler/services API, please check the API Breaking Changes page.

TypeScript 2.0

For full list of breaking changes see the breaking change issues.

No type narrowing for captured variables in functions and class expressions

Type narrowing does not cross function and class expressions, as well as lambda expressions.

Example

varx: number|string;if(typeofx==="number"){functioninner(): number{returnx;// Error, type of x is not narrowed, c is number | string}vary: number=x;// OK, x is number}

In the previous pattern the compiler can not tell when the callback will execute. Consider:

varx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}x=5;

It is wrong to assume x is a string when x.charAt() is called, as indeed it isn't.

Recommendation

Use constants instead:

constx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}

Generic type parameters are now narrowed

Example

functiong<T>(obj: T){vart: T;if(objinstanceofRegExp){t=obj;// RegExp is not assignable to T}}

Recommendation Either declare your locals to be a specific type and not the generic type parameter, or use a type assertion.

Getters with no setters are automatically inferred to be readonly properties

Example

classC{getx(){return0;}}varc=newC();c.x=1;// Error Left-hand side is a readonly property

Recommendation

Define a setter for do not write to the property.

Function declarations not allowed in blocks in strict mode

This is already a run-time error under strict mode. Starting with TypeScript 2.0, it will be flagged as a compile-time error as well.

Example

if(true){functionfoo(){}}export=foo;

Recommendation

Use function expressions instead:

if(true){constfoo=function(){}}

TemplateStringsArray is now immutable

ES2015 tagged templates always pass their tag an immutable array-like object that has a property called raw (which is also immutable). TypeScript names this object the TemplateStringsArray.

Conveniently, TemplateStringsArray was assignable to an Array<string>, so it's possible users took advantage of this to use a shorter type for their tag parameters:

functionmyTemplateTag(strs: string[]){// ...}

However, in TypeScript 2.0, the language now supports the readonly modifier and can express that these objects are immutable. As a result, TemplateStringsArray has also been made immutable, and is no longer assignable to string[].

Recommendation

Use TemplateStringsArray explicitly (or use ReadonlyArray<string>).

TypeScript 1.8

For full list of breaking changes see the breaking change issues.

Modules are now emitted with a "use strict"; prologue

Modules were always parsed in strict mode as per ES6, but for non-ES6 targets this was not respected in the generated code. Starting with TypeScript 1.8, emitted modules are always in strict mode. This shouldn't have any visible changes in most code as TS considers most strict mode errors as errors at compile time, but it means that some things which used to silently fail at runtime in your TS code, like assigning to NaN, will now loudly fail. You can reference the MDN Article on strict mode for a detailed list of the differences between strict mode and non-strict mode.

To disable this behavior, pass --noImplicitUseStrict on the command line or set it in your tsconfig.json file.

Exporting non-local names from a module

In accordance with the ES6/ES2015 spec, it is an error to export a non-local name from a module.

Example

export{Promise};// Error

Recommendation

Use a local variable declaration to capture the global name before exporting it.

constlocalPromise=Promise;export{localPromiseasPromise};

Reachability checks are enabled by default

In TypeScript 1.8 we've added a set of reachability checks to prevent certain categories of errors. Specifically

  1. check if code is reachable (enabled by default, can be disabled via allowUnreachableCode compiler option)

    functiontest1(){return1;return2;// error here}functiontest2(x){if(x){return1;}else{thrownewError("NYI")}vary=1;// error here}
  2. check if label is unused (enabled by default, can be disabled via allowUnusedLabels compiler option)

    l: // error will be reported - label `l` is unusedwhile(true){}(x)=>{x:x}// error will be reported - label `x` is unused
  3. check if all code paths in function with return type annotation return some value (disabled by default, can be enabled via noImplicitReturns compiler option)

    // error will be reported since function does not return anything explicitly when `x` is falsy.functiontest(x): number{if(x)return10;}
  4. check if control flow falls through cases in switch statement (disabled by default, can be enabled via noFallthroughCasesInSwitch compiler option). Note that cases without statements are not reported.

    switch(x){// OKcase1: case2: return1;}switch(x){case1:
    if(y)return1;case2: return2;}

If these errors are showing up in your code and you still think that scenario when they appear is legitimate you can suppress errors with compiler options.

--module is not allowed alongside --outFile unless --module is specified as one of amd or system.

Previously specifying both while using modules would result in an empty out file and no error.

Changes to DOM API's in the standard library

  • ImageData.data is now of type Uint8ClampedArray instead of number[]. See #949 for more details.
  • HTMLSelectElement .options is now of type HTMLCollection instead of HTMLSelectElement. See #1558 for more details.
  • HTMLTableElement.createCaption, HTMLTableElement.createTBody, HTMLTableElement.createTFoot, HTMLTableElement.createTHead, HTMLTableElement.insertRow, HTMLTableSectionElement.insertRow, and HTMLTableElement.insertRow now return HTMLTableRowElement instead of HTMLElement. See #3583 for more details.
  • HTMLTableRowElement.insertCell now return HTMLTableCellElement instead of HTMLElement. See #3583 for more details.
  • IDBObjectStore.createIndex and IDBDatabase.createIndex second argument is now of type IDBObjectStoreParameters instead of any. See #5932 for more details.
  • DataTransferItemList.Item returns type now is DataTransferItem instead of File. See #6106 for more details.
  • Window.open return type now is Window instead of any. See #6418 for more details.
  • WeakMap.clear as removed. See #6500 for more details.

Disallow this accessing before super-call

ES6 disallows accessing this in a constructor declaration.

For example:

classB{constructor(that?: any){}}classCextendsB{constructor(){super(this);// error;}}classDextendsB{private_prop1: number;constructor(){this._prop1=10;// errorsuper();}}

TypeScript 1.7

For full list of breaking changes see the breaking change issues.

Changes in inferring the type from this

In a class, the type of the value this will be inferred to the this type. This means subsequent assignments from values the original type can fail.

Example:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest=this;if(Math.rand()<0.5){theVeryBest=opponent;// error}returntheVeryBest}}

Recommendations:

Add a type annotation:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest: Fighter=this;if(Math.rand()<0.5){theVeryBest=opponent;// no error}returntheVeryBest}}

Automatic semicolon insertion after class member modifiers

The keywords abstract, public, protected and private are FutureReservedWords in ECMAScript 3 and are subject to automatic semicolon insertion. Previously, TypeScript did not insert semicolons when these keywords were on their own line. Now that this is fixed, abstract class D no longer correctly extends C in the following example, and instead declares a concrete method m and an additional property named abstract.

Note that async and declare already correctly did ASI.

Example:

abstractclassC{abstractm(): number;}abstractclassDextendsC{abstractm(): number;}

Recommendations:

Remove line breaks after keywords when defining class members. In general, avoid relying on automatic semicolon insertion.

TypeScript 1.6

For full list of breaking changes see the breaking change issues.

Strict object literal assignment checking

It is an error to specify properties in an object literal that were not specified on the target type, when assigned to a variable or passed for a parameter of a non-empty target type.

This new strictness can be disabled with the --suppressExcessPropertyErrors compiler option.

Example:

varx: {foo: number};x={foo: 1,baz: 2};// Error, excess property `baz`vary: {foo: number,bar?: number};y={foo: 1,baz: 2};// Error, excess or misspelled property `baz`

Recommendations:

To avoid the error, there are few remedies based on the situation you are looking into:

If the target type accepts additional properties, add an indexer:

varx: {foo: number,[x: string]: any};x={foo: 1,baz: 2};// OK, `baz` matched by index signature

If the source types are a set of related types, explicitly specify them using union types instead of just specifying the base type.

letanimalList: (Dog|Cat|Turkey)[]=[// use union type instead of Animal{name: "Milo",meow: true},{name: "Pepper",bark: true},{name: "koko",gobble: true}];

Otherwise, explicitly cast to the target type to avoid the warning message:

interfaceFoo{foo: number;}interfaceFooBar{foo: number;bar: number;}vary: Foo;y=<FooBar>{foo: 1,bar: 2};

CommonJS module resolution no longer assumes paths are relative

Previously, for the files one.ts and two.ts, an import of "one" in two.ts would resolve to one.ts if they resided in the same directory.

In TypeScript 1.6, "one" is no longer equivalent to "./one" when compiling with CommonJS. Instead, it is searched as relative to an appropriate node_modules folder as would be resolved by runtimes such as Node.js. For details, see the issue that describes the resolution algorithm.

Example:

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"one";

Recommendations:

Fix any non-relative import names that were unintended (strongly suggested).

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"./one";

Set the --moduleResolution compiler option to classic.

Function and class default export declarations can no longer merge with entities intersecting in their meaning

Declaring an entity with the same name and in the same space as a default export declaration is now an error; for example,

exportdefaultfunctionfoo(){}namespacefoo{varx=100;}

and

exportdefaultclassFoo{a: number;}interfaceFoo{b: string;}

both cause an error.

However, in the following example, merging is allowed because the namespace does does not have a meaning in the value space:

exportdefaultclassFoo{}namespaceFoo{}

Recommendations:

Declare a local for your default export and use a separate export default statement as so:

classFoo{a: number;}interfacefoo{b: string;}exportdefaultFoo;

For more details see the originating issue.

Module bodies are parsed in strict mode

In accordance with the ES6 spec, module bodies are now parsed in strict mode. module bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

Changes to DOM API's in the standard library

  • MessageEvent and ProgressEvent constructors now expect arguments; see issue #4295 for more details.
  • ImageData constructor now expects arguments; see issue #4220 for more details.
  • File constructor now expects arguments; see issue #3999 for more details.

System module output uses bulk exports

The compiler uses the new bulk-export variation of the _export function in the System module format that takes any object containing key value pairs (optionally an entire module object for export *) as arguments instead of key, value.

The module loader needs to be updated to v0.17.1 or higher.

.js content of npm package is moved from 'bin' to 'lib' folder

Entry point of TypeScript npm package was moved from bin to lib to unblock scenarios when 'node_modules/typescript/bin/typescript.js' is served from IIS (by default bin is in the list of hidden segments so IIS will block access to this folder).

TypeScript npm package does not install globally by default

TypeScript 1.6 removes the preferGlobal flag from package.json. If you rely on this behaviour please use npm install -g typescript.

Decorators are checked as call expressions

Starting with 1.6, decorators type checking is more accurate; the compiler will checks a decorator expression as a call expression with the decorated entity as a parameter. This can cause error to be reported that were not in previous releases.

TypeScript 1.5

For full list of breaking changes see the breaking change issues.

Referencing arguments in arrow functions is not allowed

This is an alignment with the ES6 semantics of arrow functions. Previously arguments within an arrow function would bind to the arrow function arguments. As per ES6 spec draft 9.2.12, arrow functions do not have an arguments objects. In TypeScript 1.5, the use of arguments object in arrow functions will be flagged as an error to ensure your code ports to ES6 with no change in semantics.

Example:

functionf(){return()=>arguments;// Error: The 'arguments' object cannot be referenced in an arrow function. }

Recommendations:

// 1. Use named rest args functionf(){return(...args)=>{args;}}// 2. Use function expressions insteadfunctionf(){returnfunction(){arguments;}}

Enum reference in-lining changes

For regular enums, pre 1.5, the compiler only inline constant members, and a member was only constant if its initializer was a literal. That resulted in inconsistent behavior depending on whether the enum value is initalized with a literal or an expression. Starting with Typescript 1.5 all non-const enum members are not inlined.

Example:

varx=E.a;// previously inlined as "var x = 1; /*E.a*/"enumE{a=1}

Recommendation: Add the const modifier to the enum declaration to ensure it is consistently inlined at all consumption sites.

For more details see issue #2183.

Contextual type flows through super and parenthesized expressions

Prior to this release, contextual types did not flow through parenthesized expressions. This has forced explicit type casts, especially in cases where parentheses are required to make an expression parse.

In the examples below, m will have a contextual type, where previously it did not.

varx: SomeType=(n)=>((m)=>q);vary: SomeType=t ? (m=>m.length) : undefined;classCextendsCBase<string>{constructor(){super({method(m){returnm.length;}});}}

See issues #1425 and #920 for more details.

DOM interface changes

TypeScript 1.5 refreshes the DOM types in lib.d.ts. This is the first major refresh since TypeScript 1.0; many IE-specific definitions have been removed in favor of the standard DOM definitions, as well as adding missing types like Web Audio and touch events.

Workaround:

You can keep using older versions of the library with newer version of the compiler. You will need to include a local copy of a previous version in your project. Here is the last released version before this change (TypeScript 1.5-alpha).

Here is a list of changes:

  • Property selection is removed from type Document
  • Property clipboardData is removed from type Window
  • Removed interface MSEventAttachmentTarget
  • Properties onresize, disabled, uniqueID, removeNode, fireEvent, currentStyle, runtimeStyle are removed from type HTMLElement
  • Property url is removed from type Event
  • Properties execScript, navigate, item are removed from type Window
  • Properties documentMode, parentWindow, createEventObject are removed from type Document
  • Property parentWindow is removed from type HTMLDocument
  • Property setCapture does not exist anywhere now
  • Property releaseCapture does not exist anywhere now
  • Properties setAttribute, styleFloat, pixelLeft are removed from type CSSStyleDeclaration
  • Property selectorText is removed from type CSSRule
  • CSSStyleSheet.rules is of type CSSRuleList instead of MSCSSRuleList
  • documentElement is of type Element instead of HTMLElement
  • Event has a new required property returnValue
  • Node has a new required property baseURI
  • Element has a new required property classList
  • Location has a new required property origin
  • Properties MSPOINTER_TYPE_MOUSE, MSPOINTER_TYPE_TOUCH are removed from type MSPointerEvent
  • CSSStyleRule has a new required property readonly
  • Property execUnsafeLocalFunction is removed from type MSApp
  • Global method toStaticHTML is removed
  • HTMLCanvasElement.getContext now returns CanvasRenderingContext2D | WebGLRenderingContex
  • Removed extension types Dataview, Weakmap, Map, Set
  • XMLHttpRequest.send has two overloads send(data?: Document): void; and send(data?: String): void;
  • window.orientation is of type string instead of number
  • IE-specific attachEvent and detachEvent are removed from Window

Here is a list of libraries that are partly or entirely replaced by the added DOM types:

  • DefinitelyTyped/auth0/auth0.d.ts
  • DefinitelyTyped/gamepad/gamepad.d.ts
  • DefinitelyTyped/interactjs/interact.d.ts
  • DefinitelyTyped/webaudioapi/waa.d.ts
  • DefinitelyTyped/webcrypto/WebCrypto.d.ts

For more details, please see the full change.

Class bodies are parsed in strict mode

In accordance with the ES6 spec, class bodies are now parsed in strict mode. Class bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

TypeScript 1.4

For full list of breaking changes see the breaking change issues.

See issue #868 for more details about breaking changes related to Union Types

Multiple Best Common Type Candidates

Given multiple viable candidates from a Best Common Type computation we now choose an item (depending on the compiler's implementation) rather than the first item.

vara: {x: number;y?: number};varb: {x: number;z?: number};// was { x: number; z?: number; }[]// now { x: number; y?: number; }[]varbs=[b,a];

This can happen in a variety of circumstances. A shared set of required properties and a disjoint set of other properties (optional or otherwise), empty types, compatible signature types (including generic and non-generic signatures when type parameters are stamped out with any).

Recommendation Provide a type annotation if you need a specific type to be chosen

varbs: {x: number;y?: number;z?: number}[]=[b,a];

Generic Type Inference

Using different types for multiple arguments of type T is now an error, even with constraints involved:

declarefunctionfoo<T>(x: T,y:T): T;varr=foo(1,"");// r used to be {}, now this is an error

With constraints:

interfaceAnimal{x}interfaceGiraffeextendsAnimal{y}interfaceElephantextendsAnimal{z}functionf<TextendsAnimal>(x: T,y: T): T{returnundefined;}varg: Giraffe;vare: Elephant;f(g,e);

See https://github.com/Microsoft/TypeScript/pull/824#discussion_r18665727 for explanation.

Recommendations Specify an explicit type parameter if the mismatch was intentional:

varr=foo<{}>(1,"");// Emulates 1.0 behaviorvarr=foo<string|number>(1,"");// Most usefulvarr=foo<any>(1,"");// Easiestf<Animal>(g,e);

or rewrite the function definition to specify that mismatches are OK:

declarefunctionfoo<T,U>(x: T,y:U): T|U;functionf<TextendsAnimal,UextendsAnimal>(x: T,y: U): T|U{returnundefined;}

Generic Rest Parameters

You cannot use heterogeneous argument types anymore:

functionmakeArray<T>(...items: T[]): T[]{returnitems;}varr=makeArray(1,"");// used to return {}[], now an error

Likewise for new Array(...)

Recommendations Declare a back-compat signature if the 1.0 behavior was desired:

functionmakeArray<T>(...items: T[]): T[];functionmakeArray(...items: {}[]): {}[];functionmakeArray<T>(...items: T[]): T[]{returnitems;}

Overload Resolution with Type Argument Inference

varf10: <T>(x: T,b: ()=>(a: T)=>void,y: T)=>T;varr9=f10('',()=>(a=>a.foo),1);// r9 was any, now this is an error

Recommendations Manually specify a type parameter

varr9=f10<any>('',()=>(a=>a.foo),1);

Strict Mode Parsing for Class Declarations and Class Expressions

ECMAScript 2015 Language Specification (ECMA-262 6th Edition) specifies that ClassDeclaration and ClassExpression are strict mode productions. Thus, additional restrictions will be applied when parsing a class declaration or class expression.

Examples:

classimplements{}// Invalid: implements is a reserved word in strict modeclassC{foo(arguments: any){// Invalid: "arguments" is not allow as a function argumentvareval=10;// Invalid: "eval" is not allowed as the left-hand-side expressionarguments=[];// Invalid: arguments object is immutable}}

For complete list of strict mode restrictions, please see Annex C - The Strict Mode of ECMAScript of ECMA-262 6th Edition.

TypeScript 1.1

For full list of breaking changes see the breaking change issues.

Working with null and undefined in ways that are observably incorrect is now an error

Examples:

varResultIsNumber17=+(null+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.varResultIsNumber18=+(null+null);// Operator '+' cannot be applied to types 'null' and 'null'.varResultIsNumber19=+(undefined+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.

Similarly, using null and undefined directly as objects that have methods now is an error

Examples:

null.toBAZ();undefined.toBAZ();

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Daniel Rosenwasser edited this page Aug 16, 2016 · 68 revisions

These changes list where implementation differs between versions as the spec and compiler are simplified and inconsistencies are corrected.

For breaking changes to the compiler/services API, please check the API Breaking Changes page.

TypeScript 2.0

For full list of breaking changes see the breaking change issues.

No type narrowing for captured variables in functions and class expressions

Type narrowing does not cross function and class expressions, as well as lambda expressions.

Example

varx: number|string;if(typeofx==="number"){functioninner(): number{returnx;// Error, type of x is not narrowed, c is number | string}vary: number=x;// OK, x is number}

In the previous pattern the compiler can not tell when the callback will execute. Consider:

varx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}x=5;

It is wrong to assume x is a string when x.charAt() is called, as indeed it isn't.

Recommendation

Use constants instead:

constx: number|string="a";if(typeofx==="string"){setTimeout(()=>console.log(x.charAt(0)),0);}

Generic type parameters are now narrowed

Example

functiong<T>(obj: T){vart: T;if(objinstanceofRegExp){t=obj;// RegExp is not assignable to T}}

Recommendation Either declare your locals to be a specific type and not the generic type parameter, or use a type assertion.

Getters with no setters are automatically inferred to be readonly properties

Example

classC{getx(){return0;}}varc=newC();c.x=1;// Error Left-hand side is a readonly property

Recommendation

Define a setter for do not write to the property.

Function declarations not allowed in blocks in strict mode

This is already a run-time error under strict mode. Starting with TypeScript 2.0, it will be flagged as a compile-time error as well.

Example

if(true){functionfoo(){}}export=foo;

Recommendation

Use function expressions instead:

if(true){constfoo=function(){}}

TemplateStringsArray is now immutable

ES2015 tagged templates always pass their tag an immutable array-like object that has a property called raw (which is also immutable). TypeScript names this object the TemplateStringsArray.

Conveniently, TemplateStringsArray was assignable to an Array<string>, so it's possible users took advantage of this to use a shorter type for their tag parameters:

functionmyTemplateTag(strs: string[]){// ...}

However, in TypeScript 2.0, the language now supports the readonly modifier and can express that these objects are immutable. As a result, TemplateStringsArray has also been made immutable, and is no longer assignable to string[].

Recommendation

Use TemplateStringsArray explicitly (or use ReadonlyArray<string>).

TypeScript 1.8

For full list of breaking changes see the breaking change issues.

Modules are now emitted with a "use strict"; prologue

Modules were always parsed in strict mode as per ES6, but for non-ES6 targets this was not respected in the generated code. Starting with TypeScript 1.8, emitted modules are always in strict mode. This shouldn't have any visible changes in most code as TS considers most strict mode errors as errors at compile time, but it means that some things which used to silently fail at runtime in your TS code, like assigning to NaN, will now loudly fail. You can reference the MDN Article on strict mode for a detailed list of the differences between strict mode and non-strict mode.

To disable this behavior, pass --noImplicitUseStrict on the command line or set it in your tsconfig.json file.

Exporting non-local names from a module

In accordance with the ES6/ES2015 spec, it is an error to export a non-local name from a module.

Example

export{Promise};// Error

Recommendation

Use a local variable declaration to capture the global name before exporting it.

constlocalPromise=Promise;export{localPromiseasPromise};

Reachability checks are enabled by default

In TypeScript 1.8 we've added a set of reachability checks to prevent certain categories of errors. Specifically

  1. check if code is reachable (enabled by default, can be disabled via allowUnreachableCode compiler option)

    functiontest1(){return1;return2;// error here}functiontest2(x){if(x){return1;}else{thrownewError("NYI")}vary=1;// error here}
  2. check if label is unused (enabled by default, can be disabled via allowUnusedLabels compiler option)

    l: // error will be reported - label `l` is unusedwhile(true){}(x)=>{x:x}// error will be reported - label `x` is unused
  3. check if all code paths in function with return type annotation return some value (disabled by default, can be enabled via noImplicitReturns compiler option)

    // error will be reported since function does not return anything explicitly when `x` is falsy.functiontest(x): number{if(x)return10;}
  4. check if control flow falls through cases in switch statement (disabled by default, can be enabled via noFallthroughCasesInSwitch compiler option). Note that cases without statements are not reported.

    switch(x){// OKcase1: case2: return1;}switch(x){case1:
    if(y)return1;case2: return2;}

If these errors are showing up in your code and you still think that scenario when they appear is legitimate you can suppress errors with compiler options.

--module is not allowed alongside --outFile unless --module is specified as one of amd or system.

Previously specifying both while using modules would result in an empty out file and no error.

Changes to DOM API's in the standard library

  • ImageData.data is now of type Uint8ClampedArray instead of number[]. See #949 for more details.
  • HTMLSelectElement .options is now of type HTMLCollection instead of HTMLSelectElement. See #1558 for more details.
  • HTMLTableElement.createCaption, HTMLTableElement.createTBody, HTMLTableElement.createTFoot, HTMLTableElement.createTHead, HTMLTableElement.insertRow, HTMLTableSectionElement.insertRow, and HTMLTableElement.insertRow now return HTMLTableRowElement instead of HTMLElement. See #3583 for more details.
  • HTMLTableRowElement.insertCell now return HTMLTableCellElement instead of HTMLElement. See #3583 for more details.
  • IDBObjectStore.createIndex and IDBDatabase.createIndex second argument is now of type IDBObjectStoreParameters instead of any. See #5932 for more details.
  • DataTransferItemList.Item returns type now is DataTransferItem instead of File. See #6106 for more details.
  • Window.open return type now is Window instead of any. See #6418 for more details.
  • WeakMap.clear as removed. See #6500 for more details.

Disallow this accessing before super-call

ES6 disallows accessing this in a constructor declaration.

For example:

classB{constructor(that?: any){}}classCextendsB{constructor(){super(this);// error;}}classDextendsB{private_prop1: number;constructor(){this._prop1=10;// errorsuper();}}

TypeScript 1.7

For full list of breaking changes see the breaking change issues.

Changes in inferring the type from this

In a class, the type of the value this will be inferred to the this type. This means subsequent assignments from values the original type can fail.

Example:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest=this;if(Math.rand()<0.5){theVeryBest=opponent;// error}returntheVeryBest}}

Recommendations:

Add a type annotation:

classFighter{/** @returns the winner of the fight. */fight(opponent: Fighter){lettheVeryBest: Fighter=this;if(Math.rand()<0.5){theVeryBest=opponent;// no error}returntheVeryBest}}

Automatic semicolon insertion after class member modifiers

The keywords abstract, public, protected and private are FutureReservedWords in ECMAScript 3 and are subject to automatic semicolon insertion. Previously, TypeScript did not insert semicolons when these keywords were on their own line. Now that this is fixed, abstract class D no longer correctly extends C in the following example, and instead declares a concrete method m and an additional property named abstract.

Note that async and declare already correctly did ASI.

Example:

abstractclassC{abstractm(): number;}abstractclassDextendsC{abstractm(): number;}

Recommendations:

Remove line breaks after keywords when defining class members. In general, avoid relying on automatic semicolon insertion.

TypeScript 1.6

For full list of breaking changes see the breaking change issues.

Strict object literal assignment checking

It is an error to specify properties in an object literal that were not specified on the target type, when assigned to a variable or passed for a parameter of a non-empty target type.

This new strictness can be disabled with the --suppressExcessPropertyErrors compiler option.

Example:

varx: {foo: number};x={foo: 1,baz: 2};// Error, excess property `baz`vary: {foo: number,bar?: number};y={foo: 1,baz: 2};// Error, excess or misspelled property `baz`

Recommendations:

To avoid the error, there are few remedies based on the situation you are looking into:

If the target type accepts additional properties, add an indexer:

varx: {foo: number,[x: string]: any};x={foo: 1,baz: 2};// OK, `baz` matched by index signature

If the source types are a set of related types, explicitly specify them using union types instead of just specifying the base type.

letanimalList: (Dog|Cat|Turkey)[]=[// use union type instead of Animal{name: "Milo",meow: true},{name: "Pepper",bark: true},{name: "koko",gobble: true}];

Otherwise, explicitly cast to the target type to avoid the warning message:

interfaceFoo{foo: number;}interfaceFooBar{foo: number;bar: number;}vary: Foo;y=<FooBar>{foo: 1,bar: 2};

CommonJS module resolution no longer assumes paths are relative

Previously, for the files one.ts and two.ts, an import of "one" in two.ts would resolve to one.ts if they resided in the same directory.

In TypeScript 1.6, "one" is no longer equivalent to "./one" when compiling with CommonJS. Instead, it is searched as relative to an appropriate node_modules folder as would be resolved by runtimes such as Node.js. For details, see the issue that describes the resolution algorithm.

Example:

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"one";

Recommendations:

Fix any non-relative import names that were unintended (strongly suggested).

./one.ts

exportfunctionf(){return10;}

./two.ts

import{fasg}from"./one";

Set the --moduleResolution compiler option to classic.

Function and class default export declarations can no longer merge with entities intersecting in their meaning

Declaring an entity with the same name and in the same space as a default export declaration is now an error; for example,

exportdefaultfunctionfoo(){}namespacefoo{varx=100;}

and

exportdefaultclassFoo{a: number;}interfaceFoo{b: string;}

both cause an error.

However, in the following example, merging is allowed because the namespace does does not have a meaning in the value space:

exportdefaultclassFoo{}namespaceFoo{}

Recommendations:

Declare a local for your default export and use a separate export default statement as so:

classFoo{a: number;}interfacefoo{b: string;}exportdefaultFoo;

For more details see the originating issue.

Module bodies are parsed in strict mode

In accordance with the ES6 spec, module bodies are now parsed in strict mode. module bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

Changes to DOM API's in the standard library

  • MessageEvent and ProgressEvent constructors now expect arguments; see issue #4295 for more details.
  • ImageData constructor now expects arguments; see issue #4220 for more details.
  • File constructor now expects arguments; see issue #3999 for more details.

System module output uses bulk exports

The compiler uses the new bulk-export variation of the _export function in the System module format that takes any object containing key value pairs (optionally an entire module object for export *) as arguments instead of key, value.

The module loader needs to be updated to v0.17.1 or higher.

.js content of npm package is moved from 'bin' to 'lib' folder

Entry point of TypeScript npm package was moved from bin to lib to unblock scenarios when 'node_modules/typescript/bin/typescript.js' is served from IIS (by default bin is in the list of hidden segments so IIS will block access to this folder).

TypeScript npm package does not install globally by default

TypeScript 1.6 removes the preferGlobal flag from package.json. If you rely on this behaviour please use npm install -g typescript.

Decorators are checked as call expressions

Starting with 1.6, decorators type checking is more accurate; the compiler will checks a decorator expression as a call expression with the decorated entity as a parameter. This can cause error to be reported that were not in previous releases.

TypeScript 1.5

For full list of breaking changes see the breaking change issues.

Referencing arguments in arrow functions is not allowed

This is an alignment with the ES6 semantics of arrow functions. Previously arguments within an arrow function would bind to the arrow function arguments. As per ES6 spec draft 9.2.12, arrow functions do not have an arguments objects. In TypeScript 1.5, the use of arguments object in arrow functions will be flagged as an error to ensure your code ports to ES6 with no change in semantics.

Example:

functionf(){return()=>arguments;// Error: The 'arguments' object cannot be referenced in an arrow function. }

Recommendations:

// 1. Use named rest args functionf(){return(...args)=>{args;}}// 2. Use function expressions insteadfunctionf(){returnfunction(){arguments;}}

Enum reference in-lining changes

For regular enums, pre 1.5, the compiler only inline constant members, and a member was only constant if its initializer was a literal. That resulted in inconsistent behavior depending on whether the enum value is initalized with a literal or an expression. Starting with Typescript 1.5 all non-const enum members are not inlined.

Example:

varx=E.a;// previously inlined as "var x = 1; /*E.a*/"enumE{a=1}

Recommendation: Add the const modifier to the enum declaration to ensure it is consistently inlined at all consumption sites.

For more details see issue #2183.

Contextual type flows through super and parenthesized expressions

Prior to this release, contextual types did not flow through parenthesized expressions. This has forced explicit type casts, especially in cases where parentheses are required to make an expression parse.

In the examples below, m will have a contextual type, where previously it did not.

varx: SomeType=(n)=>((m)=>q);vary: SomeType=t ? (m=>m.length) : undefined;classCextendsCBase<string>{constructor(){super({method(m){returnm.length;}});}}

See issues #1425 and #920 for more details.

DOM interface changes

TypeScript 1.5 refreshes the DOM types in lib.d.ts. This is the first major refresh since TypeScript 1.0; many IE-specific definitions have been removed in favor of the standard DOM definitions, as well as adding missing types like Web Audio and touch events.

Workaround:

You can keep using older versions of the library with newer version of the compiler. You will need to include a local copy of a previous version in your project. Here is the last released version before this change (TypeScript 1.5-alpha).

Here is a list of changes:

  • Property selection is removed from type Document
  • Property clipboardData is removed from type Window
  • Removed interface MSEventAttachmentTarget
  • Properties onresize, disabled, uniqueID, removeNode, fireEvent, currentStyle, runtimeStyle are removed from type HTMLElement
  • Property url is removed from type Event
  • Properties execScript, navigate, item are removed from type Window
  • Properties documentMode, parentWindow, createEventObject are removed from type Document
  • Property parentWindow is removed from type HTMLDocument
  • Property setCapture does not exist anywhere now
  • Property releaseCapture does not exist anywhere now
  • Properties setAttribute, styleFloat, pixelLeft are removed from type CSSStyleDeclaration
  • Property selectorText is removed from type CSSRule
  • CSSStyleSheet.rules is of type CSSRuleList instead of MSCSSRuleList
  • documentElement is of type Element instead of HTMLElement
  • Event has a new required property returnValue
  • Node has a new required property baseURI
  • Element has a new required property classList
  • Location has a new required property origin
  • Properties MSPOINTER_TYPE_MOUSE, MSPOINTER_TYPE_TOUCH are removed from type MSPointerEvent
  • CSSStyleRule has a new required property readonly
  • Property execUnsafeLocalFunction is removed from type MSApp
  • Global method toStaticHTML is removed
  • HTMLCanvasElement.getContext now returns CanvasRenderingContext2D | WebGLRenderingContex
  • Removed extension types Dataview, Weakmap, Map, Set
  • XMLHttpRequest.send has two overloads send(data?: Document): void; and send(data?: String): void;
  • window.orientation is of type string instead of number
  • IE-specific attachEvent and detachEvent are removed from Window

Here is a list of libraries that are partly or entirely replaced by the added DOM types:

  • DefinitelyTyped/auth0/auth0.d.ts
  • DefinitelyTyped/gamepad/gamepad.d.ts
  • DefinitelyTyped/interactjs/interact.d.ts
  • DefinitelyTyped/webaudioapi/waa.d.ts
  • DefinitelyTyped/webcrypto/WebCrypto.d.ts

For more details, please see the full change.

Class bodies are parsed in strict mode

In accordance with the ES6 spec, class bodies are now parsed in strict mode. Class bodies will behave as if "use strict" was defined at the top of their scope; this includes flagging the use of arguments and eval as variable or parameter names, use of future reserved words as variables or parameters, use of octal numeric literals, etc..

TypeScript 1.4

For full list of breaking changes see the breaking change issues.

See issue #868 for more details about breaking changes related to Union Types

Multiple Best Common Type Candidates

Given multiple viable candidates from a Best Common Type computation we now choose an item (depending on the compiler's implementation) rather than the first item.

vara: {x: number;y?: number};varb: {x: number;z?: number};// was { x: number; z?: number; }[]// now { x: number; y?: number; }[]varbs=[b,a];

This can happen in a variety of circumstances. A shared set of required properties and a disjoint set of other properties (optional or otherwise), empty types, compatible signature types (including generic and non-generic signatures when type parameters are stamped out with any).

Recommendation Provide a type annotation if you need a specific type to be chosen

varbs: {x: number;y?: number;z?: number}[]=[b,a];

Generic Type Inference

Using different types for multiple arguments of type T is now an error, even with constraints involved:

declarefunctionfoo<T>(x: T,y:T): T;varr=foo(1,"");// r used to be {}, now this is an error

With constraints:

interfaceAnimal{x}interfaceGiraffeextendsAnimal{y}interfaceElephantextendsAnimal{z}functionf<TextendsAnimal>(x: T,y: T): T{returnundefined;}varg: Giraffe;vare: Elephant;f(g,e);

See https://github.com/Microsoft/TypeScript/pull/824#discussion_r18665727 for explanation.

Recommendations Specify an explicit type parameter if the mismatch was intentional:

varr=foo<{}>(1,"");// Emulates 1.0 behaviorvarr=foo<string|number>(1,"");// Most usefulvarr=foo<any>(1,"");// Easiestf<Animal>(g,e);

or rewrite the function definition to specify that mismatches are OK:

declarefunctionfoo<T,U>(x: T,y:U): T|U;functionf<TextendsAnimal,UextendsAnimal>(x: T,y: U): T|U{returnundefined;}

Generic Rest Parameters

You cannot use heterogeneous argument types anymore:

functionmakeArray<T>(...items: T[]): T[]{returnitems;}varr=makeArray(1,"");// used to return {}[], now an error

Likewise for new Array(...)

Recommendations Declare a back-compat signature if the 1.0 behavior was desired:

functionmakeArray<T>(...items: T[]): T[];functionmakeArray(...items: {}[]): {}[];functionmakeArray<T>(...items: T[]): T[]{returnitems;}

Overload Resolution with Type Argument Inference

varf10: <T>(x: T,b: ()=>(a: T)=>void,y: T)=>T;varr9=f10('',()=>(a=>a.foo),1);// r9 was any, now this is an error

Recommendations Manually specify a type parameter

varr9=f10<any>('',()=>(a=>a.foo),1);

Strict Mode Parsing for Class Declarations and Class Expressions

ECMAScript 2015 Language Specification (ECMA-262 6th Edition) specifies that ClassDeclaration and ClassExpression are strict mode productions. Thus, additional restrictions will be applied when parsing a class declaration or class expression.

Examples:

classimplements{}// Invalid: implements is a reserved word in strict modeclassC{foo(arguments: any){// Invalid: "arguments" is not allow as a function argumentvareval=10;// Invalid: "eval" is not allowed as the left-hand-side expressionarguments=[];// Invalid: arguments object is immutable}}

For complete list of strict mode restrictions, please see Annex C - The Strict Mode of ECMAScript of ECMA-262 6th Edition.

TypeScript 1.1

For full list of breaking changes see the breaking change issues.

Working with null and undefined in ways that are observably incorrect is now an error

Examples:

varResultIsNumber17=+(null+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.varResultIsNumber18=+(null+null);// Operator '+' cannot be applied to types 'null' and 'null'.varResultIsNumber19=+(undefined+undefined);// Operator '+' cannot be applied to types 'undefined' and 'undefined'.

Similarly, using null and undefined directly as objects that have methods now is an error

Examples:

null.toBAZ();undefined.toBAZ();

Clone this wiki locally