Multiple candidates for the best generic type

When multiple best generic types are available, the compiler now makes the choice (depending on the compiler’s implementation) rather than using the first one directly.

var a: { x: number; y? : number }; var b: { x: number; z? : number }; // before {x: number; z? : number; }[] // now {x: number; y? : number; }[] var bs = [b, a];Copy the code

This can happen in a variety of situations. Has a shared set of required attributes and a set of other mutually exclusive (optional or otherwise) attributes, empty types, and compatible signature types (including generic and non-generic signatures when any is applied to type parameters).

It is recommended to use type annotations to specify the type you want to use.

var bs: { x: number; y? : number; z? : number }[] = [b, a];Copy the code

2 Generic interface

An error occurs when different types are used on multiple arguments of type T, even if constraints are added:

 declare function foo<T>(x: T, y:T): T;
 var r = foo(1, ""); // r used to be {}, now this is an error
Copy the code

Add constraint:

 interface Animal { x }
 interface Giraffe extends Animal { y }
 interface Elephant extends Animal { z }
 function f<T extends Animal>(x: T, y: T): T { return undefined; }
 var g: Giraffe;
 var e: Elephant;
 f(g, e);
Copy the code

See a full explanation here.

It is recommended that if this mismatch is intentional, then explicitly specify the type parameter:

var r = foo<{}>(1, ""); / / Emulates behaviors var r = 1.0 foo < string | number > (1, ""); // Most useful var r = foo<any>(1, ""); // Easiest f<Animal>(g, e);Copy the code

Or rewrite the function definition to say that it’s ok if it doesn’t match:

 declare function foo<T,U>(x: T, y:U): T|U;
 function f<T extends Animal, U extends Animal>(x: T, y: U): T|U { return undefined; }
Copy the code

Generic residual parameters

Can no longer use promiscuous parameter types:

function makeArray<T>(... items: T[]): T[] { return items; } var r = makeArray(1, ""); // used to return {}[], now an errorCopy the code

new Array(…) Is the same

It is recommended to declare backward compatible signatures if the 1.0 behavior is what you want:

function makeArray<T>(... items: T[]): T[]; function makeArray(... items: {}[]): {}[]; function makeArray<T>(... items: T[]): T[] { return items; }Copy the code

3. Overload resolution of interfaces with type parameters

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

Manually specifying a type parameter is recommended

 var r9 = f10<any>('', () => (a => a.foo), 1);
Copy the code

Class 4 declarations and type expressions are resolved in a strict pattern

The ECMAScript 2015 language specification (ecma-262 6th Edition) specifies the use of strict schemas for ClassDeclaration and ClassExpression. Therefore, additional restrictions are used when parsing class declarations or class expressions.

Such as:

 class implements {}  // Invalid: implements is a reserved word in strict mode
 class C {
     foo(arguments: any) {   // Invalid: "arguments" is not allow as a function argument
         var eval = 10;      // Invalid: "eval" is not allowed as the left-hand-side expression
         arguments = [];     // Invalid: arguments object is immutable
     }
 }
Copy the code

For a complete list of Strict Mode restrictions, read Annex C – The Strict Mode of ECMAScript of ECMA-262 6th Edition.