diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index bbd38ddbc5ded..7266f3b016313 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -8451,10 +8451,9 @@ namespace ts {
                 return Ternary.False;
             }
 
-            // Spec 1.0 Section 3.8.3 & 3.8.4:
-            // M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
-            source = getErasedSignature(source);
-            target = getErasedSignature(target);
+            if (source.typeParameters) {
+                source = instantiateSignatureInContextOf(source, target);
+            }
 
             let result = Ternary.True;
 
@@ -9492,23 +9491,33 @@ namespace ts {
                 const saveErrorInfo = errorInfo;
 
                 if (getObjectFlags(source) & ObjectFlags.Instantiated && getObjectFlags(target) & ObjectFlags.Instantiated && source.symbol === target.symbol) {
-                    // We instantiations of the same anonymous type (which typically will be the type of a method).
-                    // Simply do a pairwise comparison of the signatures in the two signature lists instead of the
-                    // much more expensive N * M comparison matrix we explore below.
+                    // We have instantiations of the same anonymous type (which typically will be the type of a
+                    // method). Simply do a pairwise comparison of the signatures in the two signature lists instead
+                    // of the much more expensive N * M comparison matrix we explore below. We erase type parameters
+                    // as they are known to always be the same.
                     for (let i = 0; i < targetSignatures.length; i++) {
-                        const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], reportErrors);
+                        const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors);
                         if (!related) {
                             return Ternary.False;
                         }
                         result &= related;
                     }
                 }
+                else if (sourceSignatures.length === 1 && targetSignatures.length === 1) {
+                    // For simple functions (functions with a single signature) we only erase type parameters for
+                    // the comparable relation. Otherwise, if the source signature is generic, we instantiate it
+                    // in the context of the target signature before checking the relationship. Ideally we'd do
+                    // this regardless of the number of signatures, but the potential costs are prohibitive due
+                    // to the quadratic nature of the logic below.
+                    const eraseGenerics = relation === comparableRelation || compilerOptions.noStrictGenericChecks;
+                    result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors);
+                }
                 else {
                     outer: for (const t of targetSignatures) {
                         // Only elaborate errors from the first failure
                         let shouldElaborateErrors = reportErrors;
                         for (const s of sourceSignatures) {
-                            const related = signatureRelatedTo(s, t, shouldElaborateErrors);
+                            const related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors);
                             if (related) {
                                 result &= related;
                                 errorInfo = saveErrorInfo;
@@ -9531,8 +9540,9 @@ namespace ts {
             /**
              * See signatureAssignableTo, compareSignaturesIdentical
              */
-            function signatureRelatedTo(source: Signature, target: Signature, reportErrors: boolean): Ternary {
-                return compareSignaturesRelated(source, target, /*checkAsCallback*/ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
+            function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean): Ternary {
+                return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target,
+                    /*checkAsCallback*/ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
             }
 
             function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
@@ -14980,12 +14990,15 @@ namespace ts {
         }
 
         // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
-        function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper: TypeMapper): Signature {
+        function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper): Signature {
             const context = createInferenceContext(signature, InferenceFlags.InferUnionTypes);
             forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
                 // Type parameters from outer context referenced by source type are fixed by instantiation of the source type
-                inferTypes(context.inferences, instantiateType(source, contextualMapper), target);
+                inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target);
             });
+            if (!contextualMapper) {
+                inferTypes(context.inferences, getReturnTypeOfSignature(contextualSignature), getReturnTypeOfSignature(signature), InferencePriority.ReturnType);
+            }
             return getSignatureInstantiation(signature, getInferredTypes(context));
         }
 
@@ -15025,10 +15038,10 @@ namespace ts {
                     // outer call expression. Effectively we just want a snapshot of whatever has been
                     // inferred for any outer call expression so far.
                     const instantiatedType = instantiateType(contextualType, cloneTypeMapper(getContextualMapper(node)));
-                    // If the contextual type is a generic pure function type, we instantiate the type with
-                    // its own type parameters and type arguments. This ensures that the type parameters are
-                    // not erased to type any during type inference such that they can be inferred as actual
-                    // types from the contextual type. For example:
+                    // If the contextual type is a generic function type with a single call signature, we
+                    // instantiate the type with its own type parameters and type arguments. This ensures that
+                    // the type parameters are not erased to type any during type inference such that they can
+                    // be inferred as actual types from the contextual type. For example:
                     //   declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
                     //   const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
                     // Above, the type of the 'value' parameter is inferred to be 'A'.
@@ -16362,38 +16375,43 @@ namespace ts {
             return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : neverType;
         }
 
-        function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper, checkMode: CheckMode) {
+        function inferFromAnnotatedParameters(signature: Signature, context: Signature, mapper: TypeMapper) {
             const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
-            if (checkMode === CheckMode.Inferential) {
-                for (let i = 0; i < len; i++) {
-                    const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
+            for (let i = 0; i < len; i++) {
+                const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
+                if (declaration.type) {
                     const typeNode = getEffectiveTypeAnnotationNode(declaration);
                     if (typeNode) {
                         inferTypes((<InferenceContext>mapper).inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i));
                     }
                 }
             }
+        }
+
+        function assignContextualParameterTypes(signature: Signature, context: Signature) {
+            signature.typeParameters = context.typeParameters;
             if (context.thisParameter) {
                 const parameter = signature.thisParameter;
                 if (!parameter || parameter.valueDeclaration && !(<ParameterDeclaration>parameter.valueDeclaration).type) {
                     if (!parameter) {
                         signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined);
                     }
-                    assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper, checkMode);
+                    assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter));
                 }
             }
+            const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
             for (let i = 0; i < len; i++) {
                 const parameter = signature.parameters[i];
                 if (!getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
                     const contextualParameterType = getTypeAtPosition(context, i);
-                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper, checkMode);
+                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
                 }
             }
             if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
                 const parameter = lastOrUndefined(signature.parameters);
                 if (!getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
                     const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters));
-                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper, checkMode);
+                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
                 }
             }
         }
@@ -16413,10 +16431,10 @@ namespace ts {
             }
         }
 
-        function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type, mapper: TypeMapper, checkMode: CheckMode) {
+        function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type) {
             const links = getSymbolLinks(parameter);
             if (!links.type) {
-                links.type = instantiateType(contextualType, mapper);
+                links.type = contextualType;
                 const name = getNameOfDeclaration(parameter.valueDeclaration);
                 // if inference didn't come up with anything but {}, fall back to the binding pattern if present.
                 if (links.type === emptyObjectType &&
@@ -16425,38 +16443,6 @@ namespace ts {
                 }
                 assignBindingElementTypes(<ParameterDeclaration>parameter.valueDeclaration);
             }
-            else if (checkMode === CheckMode.Inferential) {
-                // Even if the parameter already has a type, it might be because it was given a type while
-                // processing the function as an argument to a prior signature during overload resolution.
-                // If this was the case, it may have caused some type parameters to be fixed. So here,
-                // we need to ensure that type parameters at the same positions get fixed again. This is
-                // done by calling instantiateType to attach the mapper to the contextualType, and then
-                // calling inferTypes to force a walk of contextualType so that all the correct fixing
-                // happens. The choice to pass in links.type may seem kind of arbitrary, but it serves
-                // to make sure that all the correct positions in contextualType are reached by the walk.
-                // Here is an example:
-                //
-                //      interface Base {
-                //          baseProp;
-                //      }
-                //      interface Derived extends Base {
-                //          toBase(): Base;
-                //      }
-                //
-                //      var derived: Derived;
-                //
-                //      declare function foo<T>(x: T, func: (p: T) => T): T;
-                //      declare function foo<T>(x: T, func: (p: T) => T): T;
-                //
-                //      var result = foo(derived, d => d.toBase());
-                //
-                // We are typing d while checking the second overload. But we've already given d
-                // a type (Derived) from the first overload. However, we still want to fix the
-                // T in the second overload so that we do not infer Base as a candidate for T
-                // (inferring Base would make type argument inference inconsistent between the two
-                // overloads).
-                inferTypes((<InferenceContext>mapper).inferences, links.type, instantiateType(contextualType, mapper));
-            }
         }
 
         function createPromiseType(promisedType: Type): Type {
@@ -16729,37 +16715,35 @@ namespace ts {
 
             const links = getNodeLinks(node);
             const type = getTypeOfSymbol(node.symbol);
-            const contextSensitive = isContextSensitive(node);
-            const mightFixTypeParameters = contextSensitive && checkMode === CheckMode.Inferential;
 
             // Check if function expression is contextually typed and assign parameter types if so.
-            // See the comment in assignTypeToParameterAndFixTypeParameters to understand why we need to
-            // check mightFixTypeParameters.
-            if (mightFixTypeParameters || !(links.flags & NodeCheckFlags.ContextChecked)) {
+            if (!(links.flags & NodeCheckFlags.ContextChecked)) {
                 const contextualSignature = getContextualSignature(node);
                 // If a type check is started at a function expression that is an argument of a function call, obtaining the
                 // contextual type may recursively get back to here during overload resolution of the call. If so, we will have
                 // already assigned contextual types.
-                const contextChecked = !!(links.flags & NodeCheckFlags.ContextChecked);
-                if (mightFixTypeParameters || !contextChecked) {
+                if (!(links.flags & NodeCheckFlags.ContextChecked)) {
                     links.flags |= NodeCheckFlags.ContextChecked;
                     if (contextualSignature) {
                         const signature = getSignaturesOfType(type, SignatureKind.Call)[0];
-                        if (contextSensitive) {
-                            assignContextualParameterTypes(signature, contextualSignature, getContextualMapper(node), checkMode);
+                        if (isContextSensitive(node)) {
+                            const contextualMapper = getContextualMapper(node);
+                            if (checkMode === CheckMode.Inferential) {
+                                inferFromAnnotatedParameters(signature, contextualSignature, contextualMapper);
+                            }
+                            const instantiatedContextualSignature = contextualMapper === identityMapper ?
+                                contextualSignature : instantiateSignature(contextualSignature, contextualMapper);
+                            assignContextualParameterTypes(signature, instantiatedContextualSignature);
                         }
-                        if (mightFixTypeParameters || !getEffectiveReturnTypeNode(node) && !signature.resolvedReturnType) {
+                        if (!getEffectiveReturnTypeNode(node) && !signature.resolvedReturnType) {
                             const returnType = getReturnTypeFromBody(node, checkMode);
                             if (!signature.resolvedReturnType) {
                                 signature.resolvedReturnType = returnType;
                             }
                         }
                     }
-
-                    if (!contextChecked) {
-                        checkSignatureDeclaration(node);
-                        checkNodeDeferred(node);
-                    }
+                    checkSignatureDeclaration(node);
+                    checkNodeDeferred(node);
                 }
             }
 
@@ -17732,7 +17716,7 @@ namespace ts {
                 if (signature && signature.typeParameters) {
                     const contextualType = getApparentTypeOfContextualType(<Expression>node);
                     if (contextualType) {
-                        const contextualSignature = getSingleCallSignature(contextualType);
+                        const contextualSignature = getSingleCallSignature(getNonNullableType(contextualType));
                         if (contextualSignature && !contextualSignature.typeParameters) {
                             return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node)));
                         }
diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts
index 2488ad681011d..a21c9bd5cd94c 100644
--- a/src/compiler/commandLineParser.ts
+++ b/src/compiler/commandLineParser.ts
@@ -620,6 +620,12 @@ namespace ts {
             category: Diagnostics.Advanced_Options,
             description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
         },
+        {
+            name: "noStrictGenericChecks",
+            type: "boolean",
+            category: Diagnostics.Advanced_Options,
+            description: Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types,
+        },
         {
             // A list of plugins to load in the language service
             name: "plugins",
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 70efe50143e56..eda408c03e5ca 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -3278,6 +3278,10 @@
         "category": "Message",
         "code": 6184
     },
+    "Disable strict checking of generic signatures in function types.": {
+        "category": "Message",
+        "code": 6185
+    },
     "Variable '{0}' implicitly has an '{1}' type.": {
         "category": "Error",
         "code": 7005
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 28e135606d6a5..0b1f130bf6c0c 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -3522,6 +3522,7 @@ namespace ts {
         noImplicitAny?: boolean;  // Always combine with strict property
         noImplicitReturns?: boolean;
         noImplicitThis?: boolean;  // Always combine with strict property
+        noStrictGenericChecks?: boolean;
         noUnusedLocals?: boolean;
         noUnusedParameters?: boolean;
         noImplicitUseStrict?: boolean;
diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt
index 0e8605efafdc7..28fe7c738a65a 100644
--- a/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt
+++ b/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt
@@ -1,11 +1,58 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(47,1): error TS2322: Type '(x: number) => number[]' is not assignable to type '<T>(x: T) => T[]'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(50,1): error TS2322: Type '(x: number) => string[]' is not assignable to type '<T>(x: T) => string[]'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(53,1): error TS2322: Type '(x: number) => void' is not assignable to type '<T>(x: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(56,1): error TS2322: Type '(x: string, y: number) => string' is not assignable to type '<T, U>(x: T, y: U) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(59,1): error TS2322: Type '(x: (arg: string) => number) => string' is not assignable to type '<T, U>(x: (arg: T) => U) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'string' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(62,1): error TS2322: Type '(x: (arg: Base) => Derived) => Base' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(65,1): error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(68,1): error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(71,1): error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(74,1): error TS2322: Type '(...x: Derived[]) => Derived' is not assignable to type '<T extends Derived>(...x: T[]) => T'.
+  Type 'Derived' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(77,1): error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '<T extends Base>(x: T, y: T) => T'.
   Types of parameters 'y' and 'y' are incompatible.
-    Types of parameters 'arg2' and 'arg2' are incompatible.
-      Type 'Base' is not assignable to type '{ foo: string; bing: number; }'.
-        Property 'bing' is missing in type 'Base'.
+    Type 'T' is not assignable to type '{ foo: string; bar: string; }'.
+      Type 'Base' is not assignable to type '{ foo: string; bar: string; }'.
+        Property 'bar' is missing in type 'Base'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(80,1): error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Base[]>(x: Base[], y: T) => Derived[]'.
+  Types of parameters 'y' and 'y' are incompatible.
+    Type 'T' is not assignable to type 'Derived2[]'.
+      Type 'Base[]' is not assignable to type 'Derived2[]'.
+        Type 'Base' is not assignable to type 'Derived2'.
+          Property 'baz' is missing in type 'Base'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(83,1): error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '<T extends Derived[]>(x: Base[], y: T) => T'.
+  Type 'Derived[]' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(86,1): error TS2322: Type '(x: { a: string; b: number; }) => Object' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+      Types of property 'a' are incompatible.
+        Type 'T' is not assignable to type 'string'.
 
 
-==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts (1 errors) ====
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts (14 errors) ====
     // these are all permitted with the current rules, since we do not do contextual signature instantiation
     
     class Base { foo: string; }
@@ -53,51 +100,111 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
     var b: <T>(x: T) => T[]; 
     a = b; // ok
     b = a; // ok
+    ~
+!!! error TS2322: Type '(x: number) => number[]' is not assignable to type '<T>(x: T) => T[]'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'number'.
     var b2: <T>(x: T) => string[]; 
     a2 = b2; // ok 
     b2 = a2; // ok
+    ~~
+!!! error TS2322: Type '(x: number) => string[]' is not assignable to type '<T>(x: T) => string[]'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'number'.
     var b3: <T>(x: T) => T; 
     a3 = b3; // ok
     b3 = a3; // ok
+    ~~
+!!! error TS2322: Type '(x: number) => void' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'number'.
     var b4: <T, U>(x: T, y: U) => T; 
     a4 = b4; // ok
     b4 = a4; // ok
+    ~~
+!!! error TS2322: Type '(x: string, y: number) => string' is not assignable to type '<T, U>(x: T, y: U) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'string'.
     var b5: <T, U>(x: (arg: T) => U) => T; 
     a5 = b5; // ok
     b5 = a5; // ok
+    ~~
+!!! error TS2322: Type '(x: (arg: string) => number) => string' is not assignable to type '<T, U>(x: (arg: T) => U) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'string' is not assignable to type 'T'.
     var b6: <T extends Base, U extends Derived>(x: (arg: T) => U) => T; 
     a6 = b6; // ok
     b6 = a6; // ok
+    ~~
+!!! error TS2322: Type '(x: (arg: Base) => Derived) => Base' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     var b7: <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U; 
     a7 = b7; // ok
     b7 = a7; // ok
+    ~~
+!!! error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     var b8: <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U;
     a8 = b8; // ok
     b8 = a8; // ok
+    ~~
+!!! error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     var b9: <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number }) => U) => (r: T) => U; 
     a9 = b9; // ok
     b9 = a9; // ok
     ~~
 !!! error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'.
-!!! error TS2322:   Types of parameters 'y' and 'y' are incompatible.
-!!! error TS2322:     Types of parameters 'arg2' and 'arg2' are incompatible.
-!!! error TS2322:       Type 'Base' is not assignable to type '{ foo: string; bing: number; }'.
-!!! error TS2322:         Property 'bing' is missing in type 'Base'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     var b10: <T extends Derived>(...x: T[]) => T; 
     a10 = b10; // ok
     b10 = a10; // ok
+    ~~~
+!!! error TS2322: Type '(...x: Derived[]) => Derived' is not assignable to type '<T extends Derived>(...x: T[]) => T'.
+!!! error TS2322:   Type 'Derived' is not assignable to type 'T'.
     var b11: <T extends Base>(x: T, y: T) => T; 
     a11 = b11; // ok
     b11 = a11; // ok
+    ~~~
+!!! error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '<T extends Base>(x: T, y: T) => T'.
+!!! error TS2322:   Types of parameters 'y' and 'y' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type '{ foo: string; bar: string; }'.
+!!! error TS2322:       Type 'Base' is not assignable to type '{ foo: string; bar: string; }'.
+!!! error TS2322:         Property 'bar' is missing in type 'Base'.
     var b12: <T extends Array<Base>>(x: Array<Base>, y: T) => Array<Derived>; 
     a12 = b12; // ok
     b12 = a12; // ok
+    ~~~
+!!! error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Base[]>(x: Base[], y: T) => Derived[]'.
+!!! error TS2322:   Types of parameters 'y' and 'y' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'Derived2[]'.
+!!! error TS2322:       Type 'Base[]' is not assignable to type 'Derived2[]'.
+!!! error TS2322:         Type 'Base' is not assignable to type 'Derived2'.
+!!! error TS2322:           Property 'baz' is missing in type 'Base'.
     var b13: <T extends Array<Derived>>(x: Array<Base>, y: T) => T; 
     a13 = b13; // ok
     b13 = a13; // ok
+    ~~~
+!!! error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '<T extends Derived[]>(x: Base[], y: T) => T'.
+!!! error TS2322:   Type 'Derived[]' is not assignable to type 'T'.
     var b14: <T>(x: { a: T; b: T }) => T; 
     a14 = b14; // ok
     b14 = a14; // ok
+    ~~~
+!!! error TS2322: Type '(x: { a: string; b: number; }) => Object' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'T' is not assignable to type 'string'.
     var b15: <T>(x: T) => T[]; 
     a15 = b15; // ok
     b15 = a15; // ok
diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt
index df391b27f9873..39d3a2a35933e 100644
--- a/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt
+++ b/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt
@@ -1,3 +1,10 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(45,9): error TS2322: Type '(x: number) => string[]' is not assignable to type '<T, U>(x: T) => U[]'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(49,9): error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type '<T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(52,9): error TS2322: Type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U' is not assignable to type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived'.
   Types of parameters 'y' and 'y' are incompatible.
     Types of parameters 'arg2' and 'arg2' are incompatible.
@@ -5,14 +12,49 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
         Types of property 'foo' are incompatible.
           Type 'number' is not assignable to type 'string'.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(53,9): error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'.
-  Types of parameters 'y' and 'y' are incompatible.
-    Types of parameters 'arg2' and 'arg2' are incompatible.
-      Type 'Base' is not assignable to type '{ foo: number; }'.
-        Types of property 'foo' are incompatible.
-          Type 'string' is not assignable to type 'number'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(58,9): error TS2322: Type '(...x: Base[]) => Base' is not assignable to type '<T extends Derived>(...x: T[]) => T'.
+  Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(62,9): error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '<T extends Derived>(x: T, y: T) => T'.
+  Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(66,9): error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Derived2[]>(x: Base[], y: Base[]) => T'.
+  Type 'Derived[]' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(69,9): error TS2322: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
+  Type 'string | number' is not assignable to type 'number'.
+    Type 'string' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(70,9): error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+      Types of property 'a' are incompatible.
+        Type 'T' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(73,9): error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
+      Types of property 'a' are incompatible.
+        Type 'string' is not assignable to type 'Base'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(74,9): error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '<T extends Base>(x: { a: T; b: T; }) => number'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+      Types of property 'a' are incompatible.
+        Type 'T' is not assignable to type 'string'.
+          Type 'Base' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(89,9): error TS2322: Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
+  Type 'string[]' is not assignable to type 'T[]'.
+    Type 'string' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(90,9): error TS2322: Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
+  Type 'T[]' is not assignable to type 'string[]'.
+    Type 'T' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(95,9): error TS2322: Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
+  Type 'T[]' is not assignable to type 'string[]'.
+    Type 'T' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(96,9): error TS2322: Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
+  Type 'string[]' is not assignable to type 'T[]'.
+    Type 'string' is not assignable to type 'T'.
 
 
-==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts (2 errors) ====
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts (15 errors) ====
     // These are mostly permitted with the current loose rules. All ok unless otherwise noted.
     
     module Errors {
@@ -58,10 +100,19 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
             var b2: <T, U>(x: T) => U[]; 
             a2 = b2;
             b2 = a2;
+            ~~
+!!! error TS2322: Type '(x: number) => string[]' is not assignable to type '<T, U>(x: T) => U[]'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'number'.
     
             var b7: <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V;
             a7 = b7;
             b7 = a7;
+            ~~
+!!! error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type '<T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     
             var b8: <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U; 
             a8 = b8; // error, { foo: number } and Base are incompatible
@@ -75,32 +126,62 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
             b8 = a8; // error, { foo: number } and Base are incompatible
             ~~
 !!! error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'.
-!!! error TS2322:   Types of parameters 'y' and 'y' are incompatible.
-!!! error TS2322:     Types of parameters 'arg2' and 'arg2' are incompatible.
-!!! error TS2322:       Type 'Base' is not assignable to type '{ foo: number; }'.
-!!! error TS2322:         Types of property 'foo' are incompatible.
-!!! error TS2322:           Type 'string' is not assignable to type 'number'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     
             
             var b10: <T extends Derived>(...x: T[]) => T; 
             a10 = b10;
             b10 = a10;
+            ~~~
+!!! error TS2322: Type '(...x: Base[]) => Base' is not assignable to type '<T extends Derived>(...x: T[]) => T'.
+!!! error TS2322:   Type 'Base' is not assignable to type 'T'.
     
             var b11: <T extends Derived>(x: T, y: T) => T; 
             a11 = b11;
             b11 = a11;
+            ~~~
+!!! error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '<T extends Derived>(x: T, y: T) => T'.
+!!! error TS2322:   Type 'Base' is not assignable to type 'T'.
     
             var b12: <T extends Array<Derived2>>(x: Array<Base>, y: Array<Base>) => T; 
             a12 = b12;
             b12 = a12;
+            ~~~
+!!! error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Derived2[]>(x: Base[], y: Base[]) => T'.
+!!! error TS2322:   Type 'Derived[]' is not assignable to type 'T'.
     
             var b15: <T>(x: { a: T; b: T }) => T; 
             a15 = b15;
+            ~~~
+!!! error TS2322: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
+!!! error TS2322:   Type 'string | number' is not assignable to type 'number'.
+!!! error TS2322:     Type 'string' is not assignable to type 'number'.
             b15 = a15;
+            ~~~
+!!! error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'T' is not assignable to type 'string'.
     
             var b15a: <T extends Base>(x: { a: T; b: T }) => number; 
             a15 = b15a;
+            ~~~
+!!! error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'string' is not assignable to type 'Base'.
             b15a = a15;
+            ~~~~
+!!! error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '<T extends Base>(x: { a: T; b: T; }) => number'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'T' is not assignable to type 'string'.
+!!! error TS2322:           Type 'Base' is not assignable to type 'string'.
     
             var b16: <T>(x: (a: T) => T) => T[];
             a16 = b16;
@@ -116,12 +197,28 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
             var a2: <T>(x: T) => T[];
             var b2: <T>(x: T) => string[];
             a2 = b2;
+            ~~
+!!! error TS2322: Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
+!!! error TS2322:   Type 'string[]' is not assignable to type 'T[]'.
+!!! error TS2322:     Type 'string' is not assignable to type 'T'.
             b2 = a2;
+            ~~
+!!! error TS2322: Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
+!!! error TS2322:   Type 'T[]' is not assignable to type 'string[]'.
+!!! error TS2322:     Type 'T' is not assignable to type 'string'.
     
             // target type has generic call signature
             var a3: <T>(x: T) => string[];
             var b3: <T>(x: T) => T[]; 
             a3 = b3;
+            ~~
+!!! error TS2322: Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
+!!! error TS2322:   Type 'T[]' is not assignable to type 'string[]'.
+!!! error TS2322:     Type 'T' is not assignable to type 'string'.
             b3 = a3;
+            ~~
+!!! error TS2322: Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
+!!! error TS2322:   Type 'string[]' is not assignable to type 'T[]'.
+!!! error TS2322:     Type 'string' is not assignable to type 'T'.
         }
     }
\ No newline at end of file
diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures5.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures5.errors.txt
new file mode 100644
index 0000000000000..ba8f5304aa238
--- /dev/null
+++ b/tests/baselines/reference/assignmentCompatWithCallSignatures5.errors.txt
@@ -0,0 +1,93 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(40,1): error TS2322: Type '<T>(x: T) => void' is not assignable to type '<T>(x: T) => T'.
+  Type 'void' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(55,1): error TS2322: Type '<T>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
+  Type '(U | V)[]' is not assignable to type 'U[]'.
+    Type 'U | V' is not assignable to type 'U'.
+      Type 'V' is not assignable to type 'U'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(58,1): error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'.
+      Types of property 'a' are incompatible.
+        Type 'U' is not assignable to type 'Base'.
+
+
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts (3 errors) ====
+    // checking assignment compat for function types. No errors in this file
+    
+    class Base { foo: string; }
+    class Derived extends Base { bar: string; }
+    class Derived2 extends Derived { baz: string; }
+    class OtherDerived extends Base { bing: string; }
+    
+    var a: <T>(x: T) => T[];
+    var a2: <T>(x: T) => string[];
+    var a3: <T>(x: T) => void;
+    var a4: <T,U>(x: T, y: U) => string;
+    var a5: <T,U>(x: (arg: T) => U) => T;
+    var a6: <T extends Base>(x: (arg: T) => Derived) => T;
+    var a11: <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
+    var a15: <T>(x: { a: T; b: T }) => T[];
+    var a16: <T extends Base>(x: { a: T; b: T }) => T[];
+    var a17: {
+        <T extends Derived>(x: (a: T) => T): T[];
+        <T extends Base>(x: (a: T) => T): T[];        
+    };
+    var a18: {
+        (x: {
+            <T extends Derived>(a: T): T;
+            <T extends Base>(a: T): T;
+        }): any[];
+        (x: {
+            <T extends Derived2>(a: T): T;
+            <T extends Base>(a: T): T;
+        }): any[];
+    };
+    
+    var b: <T>(x: T) => T[]; 
+    a = b; // ok
+    b = a; // ok
+    var b2: <T>(x: T) => string[]; 
+    a2 = b2; // ok
+    b2 = a2; // ok
+    var b3: <T>(x: T) => T; 
+    a3 = b3; // ok
+    b3 = a3; // ok
+    ~~
+!!! error TS2322: Type '<T>(x: T) => void' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2322:   Type 'void' is not assignable to type 'T'.
+    var b4: <T, U>(x: T, y: U) => string; 
+    a4 = b4; // ok
+    b4 = a4; // ok
+    var b5: <T, U>(x: (arg: T) => U) => T; 
+    a5 = b5; // ok
+    b5 = a5; // ok
+    var b6: <T extends Base, U extends Derived>(x: (arg: T) => U) => T; 
+    a6 = b6; // ok
+    b6 = a6; // ok
+    var b11: <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base; 
+    a11 = b11; // ok
+    b11 = a11; // ok
+    var b15: <U, V>(x: { a: U; b: V; }) => U[]; 
+    a15 = b15; // ok, T = U, T = V
+    b15 = a15; // ok
+    ~~~
+!!! error TS2322: Type '<T>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
+!!! error TS2322:   Type '(U | V)[]' is not assignable to type 'U[]'.
+!!! error TS2322:     Type 'U | V' is not assignable to type 'U'.
+!!! error TS2322:       Type 'V' is not assignable to type 'U'.
+    var b16: <T>(x: { a: T; b: T }) => T[]; 
+    a15 = b16; // ok
+    b15 = a16; // ok
+    ~~~
+!!! error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'U' is not assignable to type 'Base'.
+    var b17: <T>(x: (a: T) => T) => T[]; 
+    a17 = b17; // ok
+    b17 = a17; // ok
+    var b18: (x: <T>(a: T) => T) => any[]; 
+    a18 = b18; // ok
+    b18 = a18; // ok
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures6.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures6.errors.txt
new file mode 100644
index 0000000000000..b8399a1855bcd
--- /dev/null
+++ b/tests/baselines/reference/assignmentCompatWithCallSignatures6.errors.txt
@@ -0,0 +1,61 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(30,1): error TS2322: Type '<T>(x: T) => void' is not assignable to type '<T>(x: T) => T'.
+  Type 'void' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(42,1): error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type '<T>(x: { a: T; b: T; }) => T[]'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'.
+      Types of property 'a' are incompatible.
+        Type 'T' is not assignable to type 'Base'.
+
+
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts (2 errors) ====
+    // checking assignment compatibility relations for function types. All valid
+    
+    class Base { foo: string; }
+    class Derived extends Base { bar: string; }
+    class Derived2 extends Derived { baz: string; }
+    class OtherDerived extends Base { bing: string; }
+    
+    interface A {
+        a: <T>(x: T) => T[];
+        a2: <T>(x: T) => string[];
+        a3: <T>(x: T) => void;
+        a4: <T,U>(x: T, y: U) => string;
+        a5: <T,U>(x: (arg: T) => U) => T;
+        a6: <T extends Base>(x: (arg: T) => Derived) => T;
+        a11: <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
+        a15: <T>(x: { a: T; b: T }) => T[];
+        a16: <T extends Base>(x: { a: T; b: T }) => T[];
+    }
+    
+    var x: A;
+    
+    var b: <T>(x: T) => T[]; 
+    x.a = b;
+    b = x.a;
+    var b2: <T>(x: T) => string[]; 
+    x.a2 = b2;
+    b2 = x.a2;
+    var b3: <T>(x: T) => T;
+    x.a3 = b3;
+    b3 = x.a3;
+    ~~
+!!! error TS2322: Type '<T>(x: T) => void' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2322:   Type 'void' is not assignable to type 'T'.
+    var b4: <T, U>(x: T, y: U) => string; 
+    x.a4 = b4;
+    b4 = x.a4;
+    var b5: <T, U>(x: (arg: T) => U) => T; 
+    x.a5 = b5;
+    b5 = x.a5;
+    var b11: <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base; 
+    x.a11 = b11;
+    b11 = x.a11;
+    var b16: <T>(x: { a: T; b: T }) => T[]; 
+    x.a16 = b16;
+    b16 = x.a16;
+    ~~~
+!!! error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type '<T>(x: { a: T; b: T; }) => T[]'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'T' is not assignable to type 'Base'.
\ No newline at end of file
diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt
index 995a9b67ccd72..f9a5be732c922 100644
--- a/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt
+++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt
@@ -1,11 +1,58 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(47,1): error TS2322: Type 'new (x: number) => number[]' is not assignable to type 'new <T>(x: T) => T[]'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(50,1): error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new <T>(x: T) => string[]'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(53,1): error TS2322: Type 'new (x: number) => void' is not assignable to type 'new <T>(x: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(56,1): error TS2322: Type 'new (x: string, y: number) => string' is not assignable to type 'new <T, U>(x: T, y: U) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(59,1): error TS2322: Type 'new (x: (arg: string) => number) => string' is not assignable to type 'new <T, U>(x: (arg: T) => U) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'string' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(62,1): error TS2322: Type 'new (x: (arg: Base) => Derived) => Base' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(65,1): error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(68,1): error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(71,1): error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(74,1): error TS2322: Type 'new (...x: Derived[]) => Derived' is not assignable to type 'new <T extends Derived>(...x: T[]) => T'.
+  Type 'Derived' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(77,1): error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new <T extends Base>(x: T, y: T) => T'.
   Types of parameters 'y' and 'y' are incompatible.
-    Types of parameters 'arg2' and 'arg2' are incompatible.
-      Type 'Base' is not assignable to type '{ foo: string; bing: number; }'.
-        Property 'bing' is missing in type 'Base'.
+    Type 'T' is not assignable to type '{ foo: string; bar: string; }'.
+      Type 'Base' is not assignable to type '{ foo: string; bar: string; }'.
+        Property 'bar' is missing in type 'Base'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(80,1): error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Base[]>(x: Base[], y: T) => Derived[]'.
+  Types of parameters 'y' and 'y' are incompatible.
+    Type 'T' is not assignable to type 'Derived2[]'.
+      Type 'Base[]' is not assignable to type 'Derived2[]'.
+        Type 'Base' is not assignable to type 'Derived2'.
+          Property 'baz' is missing in type 'Base'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(83,1): error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new <T extends Derived[]>(x: Base[], y: T) => T'.
+  Type 'Derived[]' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(86,1): error TS2322: Type 'new (x: { a: string; b: number; }) => Object' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+      Types of property 'a' are incompatible.
+        Type 'T' is not assignable to type 'string'.
 
 
-==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts (1 errors) ====
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts (14 errors) ====
     // checking assignment compatibility relations for function types. All of these are valid.
     
     class Base { foo: string; }
@@ -53,51 +100,111 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
     var b: new <T>(x: T) => T[]; 
     a = b; // ok
     b = a; // ok
+    ~
+!!! error TS2322: Type 'new (x: number) => number[]' is not assignable to type 'new <T>(x: T) => T[]'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'number'.
     var b2: new <T>(x: T) => string[]; 
     a2 = b2; // ok 
     b2 = a2; // ok
+    ~~
+!!! error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new <T>(x: T) => string[]'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'number'.
     var b3: new <T>(x: T) => T; 
     a3 = b3; // ok
     b3 = a3; // ok
+    ~~
+!!! error TS2322: Type 'new (x: number) => void' is not assignable to type 'new <T>(x: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'number'.
     var b4: new <T, U>(x: T, y: U) => T; 
     a4 = b4; // ok
     b4 = a4; // ok
+    ~~
+!!! error TS2322: Type 'new (x: string, y: number) => string' is not assignable to type 'new <T, U>(x: T, y: U) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'string'.
     var b5: new <T, U>(x: (arg: T) => U) => T; 
     a5 = b5; // ok
     b5 = a5; // ok
+    ~~
+!!! error TS2322: Type 'new (x: (arg: string) => number) => string' is not assignable to type 'new <T, U>(x: (arg: T) => U) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'string' is not assignable to type 'T'.
     var b6: new <T extends Base, U extends Derived>(x: (arg: T) => U) => T; 
     a6 = b6; // ok
     b6 = a6; // ok
+    ~~
+!!! error TS2322: Type 'new (x: (arg: Base) => Derived) => Base' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     var b7: new <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U; 
     a7 = b7; // ok
     b7 = a7; // ok
+    ~~
+!!! error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     var b8: new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U;
     a8 = b8; // ok
     b8 = a8; // ok
+    ~~
+!!! error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     var b9: new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number }) => U) => (r: T) => U; 
     a9 = b9; // ok
     b9 = a9; // ok
     ~~
 !!! error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'.
-!!! error TS2322:   Types of parameters 'y' and 'y' are incompatible.
-!!! error TS2322:     Types of parameters 'arg2' and 'arg2' are incompatible.
-!!! error TS2322:       Type 'Base' is not assignable to type '{ foo: string; bing: number; }'.
-!!! error TS2322:         Property 'bing' is missing in type 'Base'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     var b10: new <T extends Derived>(...x: T[]) => T; 
     a10 = b10; // ok
     b10 = a10; // ok
+    ~~~
+!!! error TS2322: Type 'new (...x: Derived[]) => Derived' is not assignable to type 'new <T extends Derived>(...x: T[]) => T'.
+!!! error TS2322:   Type 'Derived' is not assignable to type 'T'.
     var b11: new <T extends Base>(x: T, y: T) => T; 
     a11 = b11; // ok
     b11 = a11; // ok
+    ~~~
+!!! error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new <T extends Base>(x: T, y: T) => T'.
+!!! error TS2322:   Types of parameters 'y' and 'y' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type '{ foo: string; bar: string; }'.
+!!! error TS2322:       Type 'Base' is not assignable to type '{ foo: string; bar: string; }'.
+!!! error TS2322:         Property 'bar' is missing in type 'Base'.
     var b12: new <T extends Array<Base>>(x: Array<Base>, y: T) => Array<Derived>; 
     a12 = b12; // ok
     b12 = a12; // ok
+    ~~~
+!!! error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Base[]>(x: Base[], y: T) => Derived[]'.
+!!! error TS2322:   Types of parameters 'y' and 'y' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'Derived2[]'.
+!!! error TS2322:       Type 'Base[]' is not assignable to type 'Derived2[]'.
+!!! error TS2322:         Type 'Base' is not assignable to type 'Derived2'.
+!!! error TS2322:           Property 'baz' is missing in type 'Base'.
     var b13: new <T extends Array<Derived>>(x: Array<Base>, y: T) => T; 
     a13 = b13; // ok
     b13 = a13; // ok
+    ~~~
+!!! error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new <T extends Derived[]>(x: Base[], y: T) => T'.
+!!! error TS2322:   Type 'Derived[]' is not assignable to type 'T'.
     var b14: new <T>(x: { a: T; b: T }) => T; 
     a14 = b14; // ok
     b14 = a14; // ok
+    ~~~
+!!! error TS2322: Type 'new (x: { a: string; b: number; }) => Object' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'T' is not assignable to type 'string'.
     var b15: new <T>(x: T) => T[]; 
     a15 = b15; // ok
     b15 = a15; // ok
diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt
index 6b2f4a0de176d..8679b1d85f15e 100644
--- a/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt
+++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt
@@ -1,3 +1,10 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(45,9): error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new <T, U>(x: T) => U[]'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(49,9): error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type 'new <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(52,9): error TS2322: Type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U' is not assignable to type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived'.
   Types of parameters 'y' and 'y' are incompatible.
     Types of parameters 'arg2' and 'arg2' are incompatible.
@@ -5,11 +12,34 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
         Types of property 'foo' are incompatible.
           Type 'number' is not assignable to type 'string'.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(53,9): error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'.
-  Types of parameters 'y' and 'y' are incompatible.
-    Types of parameters 'arg2' and 'arg2' are incompatible.
-      Type 'Base' is not assignable to type '{ foo: number; }'.
-        Types of property 'foo' are incompatible.
-          Type 'string' is not assignable to type 'number'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Types of parameters 'arg' and 'arg' are incompatible.
+      Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(58,9): error TS2322: Type 'new (...x: Base[]) => Base' is not assignable to type 'new <T extends Derived>(...x: T[]) => T'.
+  Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(62,9): error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new <T extends Derived>(x: T, y: T) => T'.
+  Type 'Base' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(66,9): error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Derived2[]>(x: Base[], y: Base[]) => T'.
+  Type 'Derived[]' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(69,9): error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
+  Type 'string | number' is not assignable to type 'number'.
+    Type 'string' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(70,9): error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+      Types of property 'a' are incompatible.
+        Type 'T' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(73,9): error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
+      Types of property 'a' are incompatible.
+        Type 'string' is not assignable to type 'Base'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(74,9): error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new <T extends Base>(x: { a: T; b: T; }) => number'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+      Types of property 'a' are incompatible.
+        Type 'T' is not assignable to type 'string'.
+          Type 'Base' is not assignable to type 'string'.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(77,9): error TS2322: Type 'new <T>(x: (a: T) => T) => T[]' is not assignable to type '{ new (x: { new (a: number): number; new (a?: number): number; }): number[]; new (x: { new (a: boolean): boolean; new (a?: boolean): boolean; }): boolean[]; }'.
   Types of parameters 'x' and 'x' are incompatible.
     Type '{ new (a: number): number; new (a?: number): number; }' is not assignable to type '(a: any) => any'.
@@ -26,9 +56,21 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
   Types of parameters 'x' and 'x' are incompatible.
     Type '(a: any) => any' is not assignable to type '{ new <T extends Derived>(a: T): T; new <T extends Base>(a: T): T; }'.
       Type '(a: any) => any' provides no match for the signature 'new <T extends Derived>(a: T): T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(89,9): error TS2322: Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
+  Type 'string[]' is not assignable to type 'T[]'.
+    Type 'string' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(90,9): error TS2322: Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
+  Type 'T[]' is not assignable to type 'string[]'.
+    Type 'T' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(95,9): error TS2322: Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
+  Type 'T[]' is not assignable to type 'string[]'.
+    Type 'T' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(96,9): error TS2322: Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
+  Type 'string[]' is not assignable to type 'T[]'.
+    Type 'string' is not assignable to type 'T'.
 
 
-==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts (6 errors) ====
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts (19 errors) ====
     // checking assignment compatibility relations for function types.
     
     module Errors {
@@ -74,10 +116,19 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
             var b2: new <T, U>(x: T) => U[]; 
             a2 = b2; // ok
             b2 = a2; // ok
+            ~~
+!!! error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new <T, U>(x: T) => U[]'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'number'.
     
             var b7: new <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V;
             a7 = b7; // ok
             b7 = a7; // ok
+            ~~
+!!! error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type 'new <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     
             var b8: new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U; 
             a8 = b8; // error, type mismatch
@@ -91,32 +142,62 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
             b8 = a8; // error
             ~~
 !!! error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'.
-!!! error TS2322:   Types of parameters 'y' and 'y' are incompatible.
-!!! error TS2322:     Types of parameters 'arg2' and 'arg2' are incompatible.
-!!! error TS2322:       Type 'Base' is not assignable to type '{ foo: number; }'.
-!!! error TS2322:         Types of property 'foo' are incompatible.
-!!! error TS2322:           Type 'string' is not assignable to type 'number'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2322:       Type 'Base' is not assignable to type 'T'.
     
             
             var b10: new <T extends Derived>(...x: T[]) => T; 
             a10 = b10; // ok
             b10 = a10; // ok
+            ~~~
+!!! error TS2322: Type 'new (...x: Base[]) => Base' is not assignable to type 'new <T extends Derived>(...x: T[]) => T'.
+!!! error TS2322:   Type 'Base' is not assignable to type 'T'.
     
             var b11: new <T extends Derived>(x: T, y: T) => T; 
             a11 = b11; // ok
             b11 = a11; // ok
+            ~~~
+!!! error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new <T extends Derived>(x: T, y: T) => T'.
+!!! error TS2322:   Type 'Base' is not assignable to type 'T'.
     
             var b12: new <T extends Array<Derived2>>(x: Array<Base>, y: Array<Base>) => T; 
             a12 = b12; // ok
             b12 = a12; // ok
+            ~~~
+!!! error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Derived2[]>(x: Base[], y: Base[]) => T'.
+!!! error TS2322:   Type 'Derived[]' is not assignable to type 'T'.
     
             var b15: new <T>(x: { a: T; b: T }) => T; 
             a15 = b15; // ok
+            ~~~
+!!! error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
+!!! error TS2322:   Type 'string | number' is not assignable to type 'number'.
+!!! error TS2322:     Type 'string' is not assignable to type 'number'.
             b15 = a15; // ok
+            ~~~
+!!! error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'T' is not assignable to type 'string'.
     
             var b15a: new <T extends Base>(x: { a: T; b: T }) => number; 
             a15 = b15a; // ok
+            ~~~
+!!! error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'string' is not assignable to type 'Base'.
             b15a = a15; // ok
+            ~~~~
+!!! error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new <T extends Base>(x: { a: T; b: T; }) => number'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'T' is not assignable to type 'string'.
+!!! error TS2322:           Type 'Base' is not assignable to type 'string'.
     
             var b16: new <T>(x: (a: T) => T) => T[];
             a16 = b16; // error
@@ -152,12 +233,28 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
             var a2: new <T>(x: T) => T[];
             var b2: new <T>(x: T) => string[];
             a2 = b2; // ok
+            ~~
+!!! error TS2322: Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
+!!! error TS2322:   Type 'string[]' is not assignable to type 'T[]'.
+!!! error TS2322:     Type 'string' is not assignable to type 'T'.
             b2 = a2; // ok
+            ~~
+!!! error TS2322: Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
+!!! error TS2322:   Type 'T[]' is not assignable to type 'string[]'.
+!!! error TS2322:     Type 'T' is not assignable to type 'string'.
     
             // target type has generic call signature
             var a3: new <T>(x: T) => string[];
             var b3: new <T>(x: T) => T[]; 
             a3 = b3; // ok
+            ~~
+!!! error TS2322: Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
+!!! error TS2322:   Type 'T[]' is not assignable to type 'string[]'.
+!!! error TS2322:     Type 'T' is not assignable to type 'string'.
             b3 = a3; // ok
+            ~~
+!!! error TS2322: Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
+!!! error TS2322:   Type 'string[]' is not assignable to type 'T[]'.
+!!! error TS2322:     Type 'string' is not assignable to type 'T'.
         }
     }
\ No newline at end of file
diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures5.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures5.errors.txt
new file mode 100644
index 0000000000000..23e0c682fdc08
--- /dev/null
+++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures5.errors.txt
@@ -0,0 +1,93 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(40,1): error TS2322: Type 'new <T>(x: T) => void' is not assignable to type 'new <T>(x: T) => T'.
+  Type 'void' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(55,1): error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
+  Type '(U | V)[]' is not assignable to type 'U[]'.
+    Type 'U | V' is not assignable to type 'U'.
+      Type 'V' is not assignable to type 'U'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(58,1): error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'.
+      Types of property 'a' are incompatible.
+        Type 'U' is not assignable to type 'Base'.
+
+
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts (3 errors) ====
+    // checking assignment compat for function types. All valid
+    
+    class Base { foo: string; }
+    class Derived extends Base { bar: string; }
+    class Derived2 extends Derived { baz: string; }
+    class OtherDerived extends Base { bing: string; }
+    
+    var a: new <T>(x: T) => T[];
+    var a2: new <T>(x: T) => string[];
+    var a3: new <T>(x: T) => void;
+    var a4: new <T, U>(x: T, y: U) => string;
+    var a5: new <T, U>(x: new (arg: T) => U) => T;
+    var a6: new <T extends Base>(x: new (arg: T) => Derived) => T;
+    var a11: new <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
+    var a15: new <T>(x: { a: T; b: T }) => T[];
+    var a16: new <T extends Base>(x: { a: T; b: T }) => T[];
+    var a17: {
+        new <T extends Derived>(x: new (a: T) => T): T[];
+        new <T extends Base>(x: new (a: T) => T): T[];        
+    };
+    var a18: {
+        new (x: {
+            new <T extends Derived>(a: T): T;
+            new <T extends Base>(a: T): T;
+        }): any[];
+        new (x: {
+            new <T extends Derived2>(a: T): T;
+            new <T extends Base>(a: T): T;
+        }): any[];
+    };
+    
+    var b: new <T>(x: T) => T[]; 
+    a = b; // ok
+    b = a; // ok
+    var b2: new <T>(x: T) => string[]; 
+    a2 = b2; // ok
+    b2 = a2; // ok
+    var b3: new <T>(x: T) => T; 
+    a3 = b3; // ok
+    b3 = a3; // ok
+    ~~
+!!! error TS2322: Type 'new <T>(x: T) => void' is not assignable to type 'new <T>(x: T) => T'.
+!!! error TS2322:   Type 'void' is not assignable to type 'T'.
+    var b4: new <T, U>(x: T, y: U) => string; 
+    a4 = b4; // ok
+    b4 = a4; // ok
+    var b5: new <T, U>(x: new (arg: T) => U) => T; 
+    a5 = b5; // ok
+    b5 = a5; // ok
+    var b6: new <T extends Base, U extends Derived>(x: new (arg: T) => U) => T; 
+    a6 = b6; // ok
+    b6 = a6; // ok
+    var b11: new <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base; 
+    a11 = b11; // ok
+    b11 = a11; // ok
+    var b15: new <U, V>(x: { a: U; b: V; }) => U[]; 
+    a15 = b15; // ok
+    b15 = a15; // ok
+    ~~~
+!!! error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
+!!! error TS2322:   Type '(U | V)[]' is not assignable to type 'U[]'.
+!!! error TS2322:     Type 'U | V' is not assignable to type 'U'.
+!!! error TS2322:       Type 'V' is not assignable to type 'U'.
+    var b16: new <T>(x: { a: T; b: T }) => T[]; 
+    a15 = b16; // ok
+    b15 = a16; // ok
+    ~~~
+!!! error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'U' is not assignable to type 'Base'.
+    var b17: new <T>(x: new (a: T) => T) => T[]; 
+    a17 = b17; // ok
+    b17 = a17; // ok
+    var b18: new (x: new <T>(a: T) => T) => any[]; 
+    a18 = b18; // ok
+    b18 = a18; // ok
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures6.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures6.errors.txt
new file mode 100644
index 0000000000000..f89db500202ad
--- /dev/null
+++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures6.errors.txt
@@ -0,0 +1,61 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(30,1): error TS2322: Type 'new <T>(x: T) => void' is not assignable to type 'new <T>(x: T) => T'.
+  Type 'void' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(42,1): error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T[]'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'.
+      Types of property 'a' are incompatible.
+        Type 'T' is not assignable to type 'Base'.
+
+
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts (2 errors) ====
+    // checking assignment compatibility relations for function types. All valid.
+    
+    class Base { foo: string; }
+    class Derived extends Base { bar: string; }
+    class Derived2 extends Derived { baz: string; }
+    class OtherDerived extends Base { bing: string; }
+    
+    interface A {
+        a: new <T>(x: T) => T[];
+        a2: new <T>(x: T) => string[];
+        a3: new <T>(x: T) => void;
+        a4: new <T, U>(x: T, y: U) => string;
+        a5: new <T, U>(x: (arg: T) => U) => T;
+        a6: new <T extends Base>(x: (arg: T) => Derived) => T;
+        a11: new <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
+        a15: new <T>(x: { a: T; b: T }) => T[];
+        a16: new <T extends Base>(x: { a: T; b: T }) => T[];
+    }
+    
+    var x: A;
+    
+    var b: new <T>(x: T) => T[]; 
+    x.a = b;
+    b = x.a;
+    var b2: new <T>(x: T) => string[]; 
+    x.a2 = b2;
+    b2 = x.a2;
+    var b3: new <T>(x: T) => T;
+    x.a3 = b3;
+    b3 = x.a3;
+    ~~
+!!! error TS2322: Type 'new <T>(x: T) => void' is not assignable to type 'new <T>(x: T) => T'.
+!!! error TS2322:   Type 'void' is not assignable to type 'T'.
+    var b4: new <T, U>(x: T, y: U) => string; 
+    x.a4 = b4;
+    b4 = x.a4;
+    var b5: new <T, U>(x: (arg: T) => U) => T; 
+    x.a5 = b5;
+    b5 = x.a5;
+    var b11: new <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base; 
+    x.a11 = b11;
+    b11 = x.a11;
+    var b16: new <T>(x: { a: T; b: T }) => T[]; 
+    x.a16 = b16;
+    b16 = x.a16;
+    ~~~
+!!! error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T[]'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'.
+!!! error TS2322:       Types of property 'a' are incompatible.
+!!! error TS2322:         Type 'T' is not assignable to type 'Base'.
\ No newline at end of file
diff --git a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.errors.txt b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.errors.txt
new file mode 100644
index 0000000000000..7e39c3305a382
--- /dev/null
+++ b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.errors.txt
@@ -0,0 +1,27 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts(16,1): error TS2322: Type 'A' is not assignable to type 'B'.
+  Types of parameters 'y' and 'y' are incompatible.
+    Type 'S' is not assignable to type 'S[]'.
+
+
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts (1 errors) ====
+    // some complex cases of assignment compat of generic signatures. No contextual signature instantiation
+    
+    interface A {
+        <T>(x: T, ...y: T[][]): void
+    }
+    
+    interface B {
+        <S>(x: S, ...y: S[]): void
+    }
+    
+    var a: A;
+    var b: B;
+    
+    // Both ok
+    a = b;
+    b = a;
+    ~
+!!! error TS2322: Type 'A' is not assignable to type 'B'.
+!!! error TS2322:   Types of parameters 'y' and 'y' are incompatible.
+!!! error TS2322:     Type 'S' is not assignable to type 'S[]'.
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures4.errors.txt b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures4.errors.txt
new file mode 100644
index 0000000000000..a38822b8044e4
--- /dev/null
+++ b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures4.errors.txt
@@ -0,0 +1,27 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures4.ts(12,1): error TS2322: Type '<T extends I2<T>>(z: T) => void' is not assignable to type '<T extends I2<I2<T>>>(z: T) => void'.
+  Types of parameters 'z' and 'z' are incompatible.
+    Type 'T' is not assignable to type 'I2<T>'.
+      Type 'I2<I2<T>>' is not assignable to type 'I2<T>'.
+        Type 'I2<T>' is not assignable to type 'T'.
+
+
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures4.ts (1 errors) ====
+    // some complex cases of assignment compat of generic signatures.
+    
+    interface I2<T> {
+        p: T
+    }
+    
+    var x: <T extends I2<T>>(z: T) => void
+    var y: <T extends I2<I2<T>>>(z: T) => void
+    
+    // These both do not make sense as we would eventually be comparing I2<T> to I2<I2<T>>, and they are self referencing anyway
+    x = y 
+    y = x 
+    ~
+!!! error TS2322: Type '<T extends I2<T>>(z: T) => void' is not assignable to type '<T extends I2<I2<T>>>(z: T) => void'.
+!!! error TS2322:   Types of parameters 'z' and 'z' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'I2<T>'.
+!!! error TS2322:       Type 'I2<I2<T>>' is not assignable to type 'I2<T>'.
+!!! error TS2322:         Type 'I2<T>' is not assignable to type 'T'.
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.errors.txt b/tests/baselines/reference/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.errors.txt
index a18da8fd8f700..dbad415c5f83d 100644
--- a/tests/baselines/reference/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.errors.txt
+++ b/tests/baselines/reference/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.errors.txt
@@ -1,12 +1,74 @@
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(14,13): error TS2322: Type '(x: T) => any' is not assignable to type '() => T'.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(23,13): error TS2322: Type '(x: T, y: T) => any' is not assignable to type '(x: T) => T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(63,9): error TS2322: Type '() => T' is not assignable to type '<T>() => T'.
+  Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(64,9): error TS2322: Type '(x?: T) => T' is not assignable to type '<T>() => T'.
+  Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(65,9): error TS2322: Type '(x: T) => T' is not assignable to type '<T>() => T'.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(66,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>() => T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(67,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>() => T'.
+  Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(69,9): error TS2322: Type '() => T' is not assignable to type '<T>(x?: T) => T'.
+  Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(70,9): error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(71,9): error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(72,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(73,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(75,9): error TS2322: Type '() => T' is not assignable to type '<T>(x: T) => T'.
+  Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(76,9): error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(77,9): error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(78,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(79,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(81,9): error TS2322: Type '() => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+  Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(82,9): error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(83,9): error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(84,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(85,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(87,9): error TS2322: Type '() => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+  Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(88,9): error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(89,9): error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(90,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(91,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(107,13): error TS2322: Type '<T>(x: T) => any' is not assignable to type '<T>() => T'.
 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(116,13): error TS2322: Type '<T>(x: T, y: T) => any' is not assignable to type '<T>(x: T) => T'.
 
 
-==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts (6 errors) ====
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts (29 errors) ====
     // call signatures in derived types must have the same or fewer optional parameters as the target for assignment
     
     module ClassTypeParam {
@@ -74,7 +136,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
     
             // all errors
             b.a = t.a;
+            ~~~
+!!! error TS2322: Type '() => T' is not assignable to type '<T>() => T'.
+!!! error TS2322:   Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a = t.a2;
+            ~~~
+!!! error TS2322: Type '(x?: T) => T' is not assignable to type '<T>() => T'.
+!!! error TS2322:   Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a = t.a3;
             ~~~
 !!! error TS2322: Type '(x: T) => T' is not assignable to type '<T>() => T'.
@@ -82,30 +150,109 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
             ~~~
 !!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>() => T'.
             b.a = t.a5;
+            ~~~
+!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>() => T'.
+!!! error TS2322:   Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
     
             b.a2 = t.a;
+            ~~~~
+!!! error TS2322: Type '() => T' is not assignable to type '<T>(x?: T) => T'.
+!!! error TS2322:   Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a2 = t.a2;
+            ~~~~
+!!! error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a2 = t.a3;
+            ~~~~
+!!! error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a2 = t.a4;
+            ~~~~
+!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a2 = t.a5;
+            ~~~~
+!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
     
             b.a3 = t.a;
+            ~~~~
+!!! error TS2322: Type '() => T' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2322:   Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a3 = t.a2;
+            ~~~~
+!!! error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a3 = t.a3;
+            ~~~~
+!!! error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a3 = t.a4;
+            ~~~~
+!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a3 = t.a5;
+            ~~~~
+!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
     
             b.a4 = t.a;
+            ~~~~
+!!! error TS2322: Type '() => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+!!! error TS2322:   Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a4 = t.a2;
+            ~~~~
+!!! error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a4 = t.a3;
+            ~~~~
+!!! error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a4 = t.a4;
+            ~~~~
+!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a4 = t.a5;
+            ~~~~
+!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
     
             b.a5 = t.a;
+            ~~~~
+!!! error TS2322: Type '() => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+!!! error TS2322:   Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a5 = t.a2;
+            ~~~~
+!!! error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a5 = t.a3;
+            ~~~~
+!!! error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a5 = t.a4;
+            ~~~~
+!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             b.a5 = t.a5;
+            ~~~~
+!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
         }
     }
     
diff --git a/tests/baselines/reference/assignmentStricterConstraints.errors.txt b/tests/baselines/reference/assignmentStricterConstraints.errors.txt
new file mode 100644
index 0000000000000..c83e2fa3440d0
--- /dev/null
+++ b/tests/baselines/reference/assignmentStricterConstraints.errors.txt
@@ -0,0 +1,19 @@
+tests/cases/compiler/assignmentStricterConstraints.ts(7,1): error TS2322: Type '<T, S extends T>(x: T, y: S) => void' is not assignable to type '<T, S>(x: T, y: S) => void'.
+  Types of parameters 'y' and 'y' are incompatible.
+    Type 'S' is not assignable to type 'T'.
+
+
+==== tests/cases/compiler/assignmentStricterConstraints.ts (1 errors) ====
+    var f = function <T, S extends T>(x: T, y: S): void {
+        x = y
+    }
+    
+    var g = function <T, S>(x: T, y: S): void { }
+    
+    g = f
+    ~
+!!! error TS2322: Type '<T, S extends T>(x: T, y: S) => void' is not assignable to type '<T, S>(x: T, y: S) => void'.
+!!! error TS2322:   Types of parameters 'y' and 'y' are incompatible.
+!!! error TS2322:     Type 'S' is not assignable to type 'T'.
+    g(1, "")
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt
index 42940c0e41279..027551ae4b822 100644
--- a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt
+++ b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt
@@ -4,10 +4,10 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1
 tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(9,23): error TS1055: Type 'PromiseLike' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
 tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,23): error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
 tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,23): error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
-  Type 'Thenable' is not assignable to type 'PromiseLike<any>'.
+  Type 'Thenable' is not assignable to type 'PromiseLike<T>'.
     Types of property 'then' are incompatible.
-      Type '() => void' is not assignable to type '<TResult1 = any, TResult2 = never>(onfulfilled?: (value: any) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
-        Type 'void' is not assignable to type 'PromiseLike<any>'.
+      Type '() => void' is not assignable to type '<TResult1 = T, TResult2 = never>(onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
+        Type 'void' is not assignable to type 'PromiseLike<TResult1 | TResult2>'.
 tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(17,16): error TS1058: The return type of an async function must either be a valid promise or must not contain a callable 'then' member.
 tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(23,25): error TS1320: Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member.
 
@@ -35,10 +35,10 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1
 !!! error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
                           ~~~~~~~~
 !!! error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
-!!! error TS1055:   Type 'Thenable' is not assignable to type 'PromiseLike<any>'.
+!!! error TS1055:   Type 'Thenable' is not assignable to type 'PromiseLike<T>'.
 !!! error TS1055:     Types of property 'then' are incompatible.
-!!! error TS1055:       Type '() => void' is not assignable to type '<TResult1 = any, TResult2 = never>(onfulfilled?: (value: any) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
-!!! error TS1055:         Type 'void' is not assignable to type 'PromiseLike<any>'.
+!!! error TS1055:       Type '() => void' is not assignable to type '<TResult1 = T, TResult2 = never>(onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
+!!! error TS1055:         Type 'void' is not assignable to type 'PromiseLike<TResult1 | TResult2>'.
     async function fn7() { return; } // valid: Promise<void>
     async function fn8() { return 1; } // valid: Promise<number>
     async function fn9() { return null; } // valid: Promise<any>
diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt b/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt
index d6efdd6686886..3d9ecd65e3d89 100644
--- a/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt
+++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt
@@ -2,9 +2,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
   Types of property 'a' are incompatible.
     Type '(x: number) => string' is not assignable to type '(x: number) => number'.
       Type 'string' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts(63,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
+  Types of property 'a2' are incompatible.
+    Type '<T>(x: T) => string' is not assignable to type '<T>(x: T) => T'.
+      Type 'string' is not assignable to type 'T'.
 
 
-==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts (1 errors) ====
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts (2 errors) ====
     module CallSignature {
         interface Base { // T
             // M's
@@ -73,6 +77,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
     
         // S's
         interface I3 extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type '<T>(x: T) => string' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2430:       Type 'string' is not assignable to type 'T'.
             // N's
             a2: <T>(x: T) => string; // error because base returns non-void;
         }
diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt b/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt
index f5e05567b2580..5bf725b06e34a 100644
--- a/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt
+++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt
@@ -11,9 +11,31 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
           Type '{ foo: number; }' is not assignable to type 'Base'.
             Types of property 'foo' are incompatible.
               Type 'number' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(76,19): error TS2430: Interface 'I6' incorrectly extends interface 'A'.
+  Types of property 'a15' are incompatible.
+    Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
+      Type 'string | number' is not assignable to type 'number'.
+        Type 'string' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(80,19): error TS2430: Interface 'I7' incorrectly extends interface 'A'.
+  Types of property 'a15' are incompatible.
+    Type '<T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
+          Types of property 'a' are incompatible.
+            Type 'string' is not assignable to type 'Base'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(100,19): error TS2430: Interface 'I6' incorrectly extends interface 'B'.
+  Types of property 'a2' are incompatible.
+    Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
+      Type 'string[]' is not assignable to type 'T[]'.
+        Type 'string' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(109,19): error TS2430: Interface 'I7' incorrectly extends interface 'C'.
+  Types of property 'a2' are incompatible.
+    Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
+      Type 'T[]' is not assignable to type 'string[]'.
+        Type 'T' is not assignable to type 'string'.
 
 
-==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts (2 errors) ====
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts (6 errors) ====
     // checking subtype relations for function types as it relates to contextual signature instantiation
     // error cases
     
@@ -105,10 +127,24 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
             }
     
             interface I6 extends A {
+                      ~~
+!!! error TS2430: Interface 'I6' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a15' are incompatible.
+!!! error TS2430:     Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
+!!! error TS2430:       Type 'string | number' is not assignable to type 'number'.
+!!! error TS2430:         Type 'string' is not assignable to type 'number'.
                 a15: <T>(x: { a: T; b: T }) => T; // error, T is {} which isn't an acceptable return type
             }
     
             interface I7 extends A {
+                      ~~
+!!! error TS2430: Interface 'I7' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a15' are incompatible.
+!!! error TS2430:     Type '<T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
+!!! error TS2430:           Types of property 'a' are incompatible.
+!!! error TS2430:             Type 'string' is not assignable to type 'Base'.
                 a15: <T extends Base>(x: { a: T; b: T }) => number; // error, T defaults to Base, which is not compatible with number or string
             }
     
@@ -129,6 +165,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
             }
     
             interface I6 extends B {
+                      ~~
+!!! error TS2430: Interface 'I6' incorrectly extends interface 'B'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
+!!! error TS2430:       Type 'string[]' is not assignable to type 'T[]'.
+!!! error TS2430:         Type 'string' is not assignable to type 'T'.
                 a2: <T>(x: T) => string[]; // error
             }
     
@@ -138,6 +180,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
             }
     
             interface I7 extends C {
+                      ~~
+!!! error TS2430: Interface 'I7' incorrectly extends interface 'C'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
+!!! error TS2430:       Type 'T[]' is not assignable to type 'string[]'.
+!!! error TS2430:         Type 'T' is not assignable to type 'string'.
                 a2: <T>(x: T) => T[]; // error
             }
         }
diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance6.errors.txt b/tests/baselines/reference/callSignatureAssignabilityInInheritance6.errors.txt
new file mode 100644
index 0000000000000..602e40dfcfb57
--- /dev/null
+++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance6.errors.txt
@@ -0,0 +1,142 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(24,11): error TS2430: Interface 'I<T>' incorrectly extends interface 'A'.
+  Types of property 'a' are incompatible.
+    Type '(x: T) => T[]' is not assignable to type '<T>(x: T) => T[]'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(28,11): error TS2430: Interface 'I2<T>' incorrectly extends interface 'A'.
+  Types of property 'a2' are incompatible.
+    Type '(x: T) => string[]' is not assignable to type '<T>(x: T) => string[]'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(32,11): error TS2430: Interface 'I3<T>' incorrectly extends interface 'A'.
+  Types of property 'a3' are incompatible.
+    Type '(x: T) => T' is not assignable to type '<T>(x: T) => void'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(36,11): error TS2430: Interface 'I4<T>' incorrectly extends interface 'A'.
+  Types of property 'a4' are incompatible.
+    Type '<U>(x: T, y: U) => string' is not assignable to type '<T, U>(x: T, y: U) => string'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(40,11): error TS2430: Interface 'I5<T>' incorrectly extends interface 'A'.
+  Types of property 'a5' are incompatible.
+    Type '<U>(x: (arg: T) => U) => T' is not assignable to type '<T, U>(x: (arg: T) => U) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Types of parameters 'arg' and 'arg' are incompatible.
+          Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(44,11): error TS2430: Interface 'I7<T>' incorrectly extends interface 'A'.
+  Types of property 'a11' are incompatible.
+    Type '<U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type '<T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated.
+          Types of property 'foo' are incompatible.
+            Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(48,11): error TS2430: Interface 'I9<T>' incorrectly extends interface 'A'.
+  Types of property 'a16' are incompatible.
+    Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '<T extends Base>(x: { a: T; b: T; }) => T[]'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated.
+          Types of property 'a' are incompatible.
+            Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+              Type 'Base' is not assignable to type 'T'.
+
+
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts (7 errors) ====
+    // checking subtype relations for function types as it relates to contextual signature instantiation
+    // same as subtypingWithCallSignatures4 but using class type parameters instead of generic signatures
+    // all are errors
+    
+    class Base { foo: string; }
+    class Derived extends Base { bar: string; }
+    class Derived2 extends Derived { baz: string; }
+    class OtherDerived extends Base { bing: string; }
+    
+    interface A { // T
+        // M's
+        a: <T>(x: T) => T[];
+        a2: <T>(x: T) => string[];
+        a3: <T>(x: T) => void;
+        a4: <T,U>(x: T, y: U) => string;
+        a5: <T,U>(x: (arg: T) => U) => T;
+        a6: <T extends Base>(x: (arg: T) => Derived) => T;
+        a11: <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
+        a15: <T>(x: { a: T; b: T }) => T[];
+        a16: <T extends Base>(x: { a: T; b: T }) => T[];
+    }
+    
+    // S's
+    interface I<T> extends A {
+              ~
+!!! error TS2430: Interface 'I<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a' are incompatible.
+!!! error TS2430:     Type '(x: T) => T[]' is not assignable to type '<T>(x: T) => T[]'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a: (x: T) => T[]; 
+    }
+    
+    interface I2<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I2<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type '(x: T) => string[]' is not assignable to type '<T>(x: T) => string[]'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a2: (x: T) => string[]; 
+    }
+    
+    interface I3<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I3<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a3' are incompatible.
+!!! error TS2430:     Type '(x: T) => T' is not assignable to type '<T>(x: T) => void'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a3: (x: T) => T;
+    }
+    
+    interface I4<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I4<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type '<U>(x: T, y: U) => string' is not assignable to type '<T, U>(x: T, y: U) => string'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a4: <U>(x: T, y: U) => string; 
+    }
+    
+    interface I5<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I5<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type '<U>(x: (arg: T) => U) => T' is not assignable to type '<T, U>(x: (arg: T) => U) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2430:           Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a5: <U>(x: (arg: T) => U) => T; 
+    }
+    
+    interface I7<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I7<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a11' are incompatible.
+!!! error TS2430:     Type '<U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type '<T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated.
+!!! error TS2430:           Types of property 'foo' are incompatible.
+!!! error TS2430:             Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a11: <U>(x: { foo: T }, y: { foo: U; bar: U }) => Base; 
+    }
+    
+    interface I9<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I9<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a16' are incompatible.
+!!! error TS2430:     Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '<T extends Base>(x: { a: T; b: T; }) => T[]'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated.
+!!! error TS2430:           Types of property 'a' are incompatible.
+!!! error TS2430:             Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+!!! error TS2430:               Type 'Base' is not assignable to type 'T'.
+        a16: (x: { a: T; b: T }) => T[]; 
+    }
\ No newline at end of file
diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt b/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt
index 51278fc3f442f..cc2c1e871e5ed 100644
--- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt
+++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt
@@ -2,9 +2,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
   Types of property 'a' are incompatible.
     Type 'new (x: number) => string' is not assignable to type 'new (x: number) => number'.
       Type 'string' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts(67,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
+  Types of property 'a2' are incompatible.
+    Type 'new <T>(x: T) => string' is not assignable to type 'new <T>(x: T) => T'.
+      Type 'string' is not assignable to type 'T'.
 
 
-==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts (1 errors) ====
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts (2 errors) ====
     // Checking basic subtype relations with construct signatures
     
     module ConstructSignature {
@@ -77,6 +81,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
     
         // S's
         interface I3 extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type 'new <T>(x: T) => string' is not assignable to type 'new <T>(x: T) => T'.
+!!! error TS2430:       Type 'string' is not assignable to type 'T'.
             // N's
             a2: new <T>(x: T) => string; // error because base returns non-void;
         }
diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt b/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt
index 7bd761593912f..9646acd071ffa 100644
--- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt
+++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt
@@ -11,9 +11,31 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
           Type '{ foo: number; }' is not assignable to type 'Base'.
             Types of property 'foo' are incompatible.
               Type 'number' is not assignable to type 'string'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(66,19): error TS2430: Interface 'I6' incorrectly extends interface 'A'.
+  Types of property 'a15' are incompatible.
+    Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
+      Type 'string | number' is not assignable to type 'number'.
+        Type 'string' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(70,19): error TS2430: Interface 'I7' incorrectly extends interface 'A'.
+  Types of property 'a15' are incompatible.
+    Type 'new <T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
+          Types of property 'a' are incompatible.
+            Type 'string' is not assignable to type 'Base'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(86,19): error TS2430: Interface 'I6' incorrectly extends interface 'B'.
+  Types of property 'a2' are incompatible.
+    Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
+      Type 'string[]' is not assignable to type 'T[]'.
+        Type 'string' is not assignable to type 'T'.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(95,19): error TS2430: Interface 'I7' incorrectly extends interface 'C'.
+  Types of property 'a2' are incompatible.
+    Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
+      Type 'T[]' is not assignable to type 'string[]'.
+        Type 'T' is not assignable to type 'string'.
 
 
-==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts (2 errors) ====
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts (6 errors) ====
     // checking subtype relations for function types as it relates to contextual signature instantiation
     // error cases
     
@@ -95,10 +117,24 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
             }
     
             interface I6 extends A {
+                      ~~
+!!! error TS2430: Interface 'I6' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a15' are incompatible.
+!!! error TS2430:     Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
+!!! error TS2430:       Type 'string | number' is not assignable to type 'number'.
+!!! error TS2430:         Type 'string' is not assignable to type 'number'.
                 a15: new <T>(x: { a: T; b: T }) => T; // error, T is {} which isn't an acceptable return type
             }
     
             interface I7 extends A {
+                      ~~
+!!! error TS2430: Interface 'I7' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a15' are incompatible.
+!!! error TS2430:     Type 'new <T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
+!!! error TS2430:           Types of property 'a' are incompatible.
+!!! error TS2430:             Type 'string' is not assignable to type 'Base'.
                 a15: new <T extends Base>(x: { a: T; b: T }) => number; // error, T defaults to Base, which is not compatible with number or string
             }
     
@@ -115,6 +151,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
             }
     
             interface I6 extends B {
+                      ~~
+!!! error TS2430: Interface 'I6' incorrectly extends interface 'B'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
+!!! error TS2430:       Type 'string[]' is not assignable to type 'T[]'.
+!!! error TS2430:         Type 'string' is not assignable to type 'T'.
                 a2: new <T>(x: T) => string[]; // error
             }
     
@@ -124,6 +166,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
             }
     
             interface I7 extends C {
+                      ~~
+!!! error TS2430: Interface 'I7' incorrectly extends interface 'C'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
+!!! error TS2430:       Type 'T[]' is not assignable to type 'string[]'.
+!!! error TS2430:         Type 'T' is not assignable to type 'string'.
                 a2: new <T>(x: T) => T[]; // error
             }
     
diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance6.errors.txt b/tests/baselines/reference/constructSignatureAssignabilityInInheritance6.errors.txt
new file mode 100644
index 0000000000000..6245fead91964
--- /dev/null
+++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance6.errors.txt
@@ -0,0 +1,142 @@
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(24,11): error TS2430: Interface 'I<T>' incorrectly extends interface 'A'.
+  Types of property 'a' are incompatible.
+    Type 'new (x: T) => T[]' is not assignable to type 'new <T>(x: T) => T[]'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(28,11): error TS2430: Interface 'I2<T>' incorrectly extends interface 'A'.
+  Types of property 'a2' are incompatible.
+    Type 'new (x: T) => string[]' is not assignable to type 'new <T>(x: T) => string[]'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(32,11): error TS2430: Interface 'I3<T>' incorrectly extends interface 'A'.
+  Types of property 'a3' are incompatible.
+    Type 'new (x: T) => T' is not assignable to type 'new <T>(x: T) => void'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(36,11): error TS2430: Interface 'I4<T>' incorrectly extends interface 'A'.
+  Types of property 'a4' are incompatible.
+    Type 'new <U>(x: T, y: U) => string' is not assignable to type 'new <T, U>(x: T, y: U) => string'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(40,11): error TS2430: Interface 'I5<T>' incorrectly extends interface 'A'.
+  Types of property 'a5' are incompatible.
+    Type 'new <U>(x: (arg: T) => U) => T' is not assignable to type 'new <T, U>(x: (arg: T) => U) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Types of parameters 'arg' and 'arg' are incompatible.
+          Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(44,11): error TS2430: Interface 'I7<T>' incorrectly extends interface 'A'.
+  Types of property 'a11' are incompatible.
+    Type 'new <U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type 'new <T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated.
+          Types of property 'foo' are incompatible.
+            Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(48,11): error TS2430: Interface 'I9<T>' incorrectly extends interface 'A'.
+  Types of property 'a16' are incompatible.
+    Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T extends Base>(x: { a: T; b: T; }) => T[]'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated.
+          Types of property 'a' are incompatible.
+            Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+              Type 'Base' is not assignable to type 'T'.
+
+
+==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts (7 errors) ====
+    // checking subtype relations for function types as it relates to contextual signature instantiation
+    // same as subtypingWithConstructSignatures4 but using class type parameters instead of generic signatures
+    // all are errors
+    
+    class Base { foo: string; }
+    class Derived extends Base { bar: string; }
+    class Derived2 extends Derived { baz: string; }
+    class OtherDerived extends Base { bing: string; }
+    
+    interface A { // T
+        // M's
+        a: new <T>(x: T) => T[];
+        a2: new <T>(x: T) => string[];
+        a3: new <T>(x: T) => void;
+        a4: new <T, U>(x: T, y: U) => string;
+        a5: new <T, U>(x: (arg: T) => U) => T;
+        a6: new <T extends Base>(x: (arg: T) => Derived) => T;
+        a11: new <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
+        a15: new <T>(x: { a: T; b: T }) => T[];
+        a16: new <T extends Base>(x: { a: T; b: T }) => T[];
+    }
+    
+    // S's
+    interface I<T> extends A {
+              ~
+!!! error TS2430: Interface 'I<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a' are incompatible.
+!!! error TS2430:     Type 'new (x: T) => T[]' is not assignable to type 'new <T>(x: T) => T[]'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a: new (x: T) => T[]; 
+    }
+    
+    interface I2<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I2<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type 'new (x: T) => string[]' is not assignable to type 'new <T>(x: T) => string[]'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a2: new (x: T) => string[]; 
+    }
+    
+    interface I3<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I3<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a3' are incompatible.
+!!! error TS2430:     Type 'new (x: T) => T' is not assignable to type 'new <T>(x: T) => void'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a3: new (x: T) => T;
+    }
+    
+    interface I4<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I4<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type 'new <U>(x: T, y: U) => string' is not assignable to type 'new <T, U>(x: T, y: U) => string'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a4: new <U>(x: T, y: U) => string; 
+    }
+    
+    interface I5<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I5<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type 'new <U>(x: (arg: T) => U) => T' is not assignable to type 'new <T, U>(x: (arg: T) => U) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2430:           Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a5: new <U>(x: (arg: T) => U) => T; 
+    }
+    
+    interface I7<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I7<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a11' are incompatible.
+!!! error TS2430:     Type 'new <U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type 'new <T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated.
+!!! error TS2430:           Types of property 'foo' are incompatible.
+!!! error TS2430:             Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a11: new <U>(x: { foo: T }, y: { foo: U; bar: U }) => Base; 
+    }
+    
+    interface I9<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I9<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a16' are incompatible.
+!!! error TS2430:     Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T extends Base>(x: { a: T; b: T; }) => T[]'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated.
+!!! error TS2430:           Types of property 'a' are incompatible.
+!!! error TS2430:             Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+!!! error TS2430:               Type 'Base' is not assignable to type 'T'.
+        a16: new (x: { a: T; b: T }) => T[]; 
+    }
\ No newline at end of file
diff --git a/tests/baselines/reference/contextualTypingWithGenericSignature.types b/tests/baselines/reference/contextualTypingWithGenericSignature.types
index e662f2c419252..cb70022a20b0d 100644
--- a/tests/baselines/reference/contextualTypingWithGenericSignature.types
+++ b/tests/baselines/reference/contextualTypingWithGenericSignature.types
@@ -16,9 +16,9 @@ var f2: {
 };
 
 f2 = (x, y) => { return x }
->f2 = (x, y) => { return x } : (x: T, y: U) => T
+>f2 = (x, y) => { return x } : <T, U>(x: T, y: U) => T
 >f2 : <T, U>(x: T, y: U) => T
->(x, y) => { return x } : (x: T, y: U) => T
+>(x, y) => { return x } : <T, U>(x: T, y: U) => T
 >x : T
 >y : U
 >x : T
diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly1.symbols b/tests/baselines/reference/fixingTypeParametersRepeatedly1.symbols
index 86f91c826633c..3d0c33ebfc04c 100644
--- a/tests/baselines/reference/fixingTypeParametersRepeatedly1.symbols
+++ b/tests/baselines/reference/fixingTypeParametersRepeatedly1.symbols
@@ -45,7 +45,5 @@ g("", x => null, x => x.toLowerCase());
 >g : Symbol(g, Decl(fixingTypeParametersRepeatedly1.ts, 1, 39), Decl(fixingTypeParametersRepeatedly1.ts, 4, 63))
 >x : Symbol(x, Decl(fixingTypeParametersRepeatedly1.ts, 6, 5))
 >x : Symbol(x, Decl(fixingTypeParametersRepeatedly1.ts, 6, 16))
->x.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
 >x : Symbol(x, Decl(fixingTypeParametersRepeatedly1.ts, 6, 16))
->toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
 
diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly1.types b/tests/baselines/reference/fixingTypeParametersRepeatedly1.types
index 41e705ba94353..d7326a515f515 100644
--- a/tests/baselines/reference/fixingTypeParametersRepeatedly1.types
+++ b/tests/baselines/reference/fixingTypeParametersRepeatedly1.types
@@ -48,16 +48,16 @@ declare function g();
 >g : { <T>(x: T, y: (p: T) => T, z: (p: T) => T): T; (): any; }
 
 g("", x => null, x => x.toLowerCase());
->g("", x => null, x => x.toLowerCase()) : string
+>g("", x => null, x => x.toLowerCase()) : any
 >g : { <T>(x: T, y: (p: T) => T, z: (p: T) => T): T; (): any; }
 >"" : ""
 >x => null : (x: string) => any
 >x : string
 >null : null
->x => x.toLowerCase() : (x: string) => string
->x : string
->x.toLowerCase() : string
->x.toLowerCase : () => string
->x : string
->toLowerCase : () => string
+>x => x.toLowerCase() : (x: any) => any
+>x : any
+>x.toLowerCase() : any
+>x.toLowerCase : any
+>x : any
+>toLowerCase : any
 
diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt b/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt
index e56b58a268d12..900d605d5fc19 100644
--- a/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt
+++ b/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt
@@ -1,11 +1,9 @@
 tests/cases/compiler/fixingTypeParametersRepeatedly2.ts(11,27): error TS2345: Argument of type '(d: Derived) => Base' is not assignable to parameter of type '(p: Derived) => Derived'.
   Type 'Base' is not assignable to type 'Derived'.
     Property 'toBase' is missing in type 'Base'.
-tests/cases/compiler/fixingTypeParametersRepeatedly2.ts(17,27): error TS2345: Argument of type '(d: Derived) => Base' is not assignable to parameter of type '(p: Derived) => Derived'.
-  Type 'Base' is not assignable to type 'Derived'.
 
 
-==== tests/cases/compiler/fixingTypeParametersRepeatedly2.ts (2 errors) ====
+==== tests/cases/compiler/fixingTypeParametersRepeatedly2.ts (1 errors) ====
     interface Base {
         baseProp;
     }
@@ -26,7 +24,4 @@ tests/cases/compiler/fixingTypeParametersRepeatedly2.ts(17,27): error TS2345: Ar
     // The same error should be observed in both cases.
     declare function bar<T>(x: T, func: (p: T) => T): T;
     declare function bar<T>(x: T, func: (p: T) => T): T;
-    var result = bar(derived, d => d.toBase());
-                              ~~~~~~~~~~~~~~~
-!!! error TS2345: Argument of type '(d: Derived) => Base' is not assignable to parameter of type '(p: Derived) => Derived'.
-!!! error TS2345:   Type 'Base' is not assignable to type 'Derived'.
\ No newline at end of file
+    var result = bar(derived, d => d.toBase());
\ No newline at end of file
diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly3.types b/tests/baselines/reference/fixingTypeParametersRepeatedly3.types
index 3bf926276d28c..beb195df5edce 100644
--- a/tests/baselines/reference/fixingTypeParametersRepeatedly3.types
+++ b/tests/baselines/reference/fixingTypeParametersRepeatedly3.types
@@ -66,8 +66,8 @@ declare function bar<T>(x: T, func: (p: T) => T): T;
 >T : T
 
 var result2 = bar(derived, d => d.toBase());
->result2 : Derived
->bar(derived, d => d.toBase()) : Derived
+>result2 : Base
+>bar(derived, d => d.toBase()) : Base
 >bar : { <T>(x: T, func: (p: T) => T): T; <T>(x: T, func: (p: T) => T): T; }
 >derived : Derived
 >d => d.toBase() : (d: Derived) => Base
diff --git a/tests/baselines/reference/functionTypeArgumentAssignmentCompat.errors.txt b/tests/baselines/reference/functionTypeArgumentAssignmentCompat.errors.txt
index 366e1732b292e..2fa3cafcb1ac9 100644
--- a/tests/baselines/reference/functionTypeArgumentAssignmentCompat.errors.txt
+++ b/tests/baselines/reference/functionTypeArgumentAssignmentCompat.errors.txt
@@ -1,7 +1,9 @@
+tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts(9,1): error TS2322: Type '<S>() => S[]' is not assignable to type '<T>(x: T) => T'.
+  Type '{}[]' is not assignable to type 'T'.
 tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts(12,1): error TS2304: Cannot find name 'console'.
 
 
-==== tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts (1 errors) ====
+==== tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts (2 errors) ====
     var f : {
      <T>(x:T): T;
     }
@@ -11,6 +13,9 @@ tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts(12,1): error TS2304
     } = () => [];
     
     f = g;
+    ~
+!!! error TS2322: Type '<S>() => S[]' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2322:   Type '{}[]' is not assignable to type 'T'.
     var s = f("str").toUpperCase();
     
     console.log(s);
diff --git a/tests/baselines/reference/genericArgumentCallSigAssignmentCompat.errors.txt b/tests/baselines/reference/genericArgumentCallSigAssignmentCompat.errors.txt
new file mode 100644
index 0000000000000..9e9a7e9505d05
--- /dev/null
+++ b/tests/baselines/reference/genericArgumentCallSigAssignmentCompat.errors.txt
@@ -0,0 +1,30 @@
+tests/cases/compiler/genericArgumentCallSigAssignmentCompat.ts(16,31): error TS2345: Argument of type '<T>(value: T) => T' is not assignable to parameter of type 'Iterator<string | number | boolean, boolean>'.
+  Type 'string | number | boolean' is not assignable to type 'boolean'.
+    Type 'string' is not assignable to type 'boolean'.
+
+
+==== tests/cases/compiler/genericArgumentCallSigAssignmentCompat.ts (1 errors) ====
+    module Underscore {
+        export interface Iterator<T, U> {
+            (value: T, index: any, list: any): U;
+        }
+     
+        export interface Static {
+            all<T>(list: T[], iterator?: Iterator<T, boolean>, context?: any): boolean;
+            identity<T>(value: T): T;
+        }
+    }
+     
+    declare var _: Underscore.Static;
+     
+    // No error, Call signatures of types '<T>(value: T) => T' and 'Underscore.Iterator<{}, boolean>' are compatible when instantiated with any.
+    // Ideally, we would not have a generic signature here, because it should be instantiated with {} during inferential typing
+    _.all([true, 1, null, 'yes'], _.identity);
+                                  ~~~~~~~~~~
+!!! error TS2345: Argument of type '<T>(value: T) => T' is not assignable to parameter of type 'Iterator<string | number | boolean, boolean>'.
+!!! error TS2345:   Type 'string | number | boolean' is not assignable to type 'boolean'.
+!!! error TS2345:     Type 'string' is not assignable to type 'boolean'.
+     
+    // Ok, because fixing makes us infer boolean for T
+    _.all([true], _.identity);
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/genericAssignmentCompatOfFunctionSignatures1.errors.txt b/tests/baselines/reference/genericAssignmentCompatOfFunctionSignatures1.errors.txt
new file mode 100644
index 0000000000000..b2c6aa42013d9
--- /dev/null
+++ b/tests/baselines/reference/genericAssignmentCompatOfFunctionSignatures1.errors.txt
@@ -0,0 +1,34 @@
+tests/cases/compiler/genericAssignmentCompatOfFunctionSignatures1.ts(4,1): error TS2322: Type '<T, U extends { a: T; b: number; }>(x: T, z: U) => void' is not assignable to type '<T, U extends { a: T; b: string; }>(x: T, z: U) => void'.
+  Types of parameters 'z' and 'z' are incompatible.
+    Type 'U' is not assignable to type '{ a: T; b: number; }'.
+      Type '{ a: T; b: string; }' is not assignable to type '{ a: T; b: number; }'.
+        Types of property 'b' are incompatible.
+          Type 'string' is not assignable to type 'number'.
+tests/cases/compiler/genericAssignmentCompatOfFunctionSignatures1.ts(5,1): error TS2322: Type '<T, U extends { a: T; b: string; }>(x: T, z: U) => void' is not assignable to type '<T, U extends { a: T; b: number; }>(x: T, z: U) => void'.
+  Types of parameters 'z' and 'z' are incompatible.
+    Type 'U' is not assignable to type '{ a: T; b: string; }'.
+      Type '{ a: T; b: number; }' is not assignable to type '{ a: T; b: string; }'.
+        Types of property 'b' are incompatible.
+          Type 'number' is not assignable to type 'string'.
+
+
+==== tests/cases/compiler/genericAssignmentCompatOfFunctionSignatures1.ts (2 errors) ====
+    var x1 = function foo3<T, U extends { a: T; b: string }>(x: T, z: U) { }
+    var x2 = function foo3<T, U extends { a: T; b: number }>(x: T, z: U) { }
+    
+    x1 = x2;
+    ~~
+!!! error TS2322: Type '<T, U extends { a: T; b: number; }>(x: T, z: U) => void' is not assignable to type '<T, U extends { a: T; b: string; }>(x: T, z: U) => void'.
+!!! error TS2322:   Types of parameters 'z' and 'z' are incompatible.
+!!! error TS2322:     Type 'U' is not assignable to type '{ a: T; b: number; }'.
+!!! error TS2322:       Type '{ a: T; b: string; }' is not assignable to type '{ a: T; b: number; }'.
+!!! error TS2322:         Types of property 'b' are incompatible.
+!!! error TS2322:           Type 'string' is not assignable to type 'number'.
+    x2 = x1;
+    ~~
+!!! error TS2322: Type '<T, U extends { a: T; b: string; }>(x: T, z: U) => void' is not assignable to type '<T, U extends { a: T; b: number; }>(x: T, z: U) => void'.
+!!! error TS2322:   Types of parameters 'z' and 'z' are incompatible.
+!!! error TS2322:     Type 'U' is not assignable to type '{ a: T; b: string; }'.
+!!! error TS2322:       Type '{ a: T; b: number; }' is not assignable to type '{ a: T; b: string; }'.
+!!! error TS2322:         Types of property 'b' are incompatible.
+!!! error TS2322:           Type 'number' is not assignable to type 'string'.
\ No newline at end of file
diff --git a/tests/baselines/reference/genericContextualTypes1.types b/tests/baselines/reference/genericContextualTypes1.types
index 4aedcd6e81b22..b1a7aff8eef9f 100644
--- a/tests/baselines/reference/genericContextualTypes1.types
+++ b/tests/baselines/reference/genericContextualTypes1.types
@@ -125,7 +125,7 @@ const f01: <A>(x: A) => A[] = x => [x];
 >x : A
 >A : A
 >A : A
->x => [x] : (x: A) => A[]
+>x => [x] : <A>(x: A) => A[]
 >x : A
 >[x] : A[]
 >x : A
@@ -356,7 +356,7 @@ type fn = <A>(a: A) => A;
 const fn: fn = a => a;
 >fn : fn
 >fn : fn
->a => a : (a: A) => A
+>a => a : <A>(a: A) => A
 >a : A
 >a : A
 
diff --git a/tests/baselines/reference/genericFunctionCallSignatureReturnTypeMismatch.errors.txt b/tests/baselines/reference/genericFunctionCallSignatureReturnTypeMismatch.errors.txt
index a1051e0b020a3..a0c5cbb437803 100644
--- a/tests/baselines/reference/genericFunctionCallSignatureReturnTypeMismatch.errors.txt
+++ b/tests/baselines/reference/genericFunctionCallSignatureReturnTypeMismatch.errors.txt
@@ -1,13 +1,18 @@
+tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts(6,1): error TS2322: Type '<S>() => S[]' is not assignable to type '<T>(x: T) => T'.
+  Type '{}[]' is not assignable to type 'T'.
 tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts(10,1): error TS2304: Cannot find name 'console'.
 
 
-==== tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts (1 errors) ====
+==== tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts (2 errors) ====
     interface Array<T> {}
     
     var f : { <T>(x:T): T; }
     
     var g : { <S>() : S[]; };
     f = g;
+    ~
+!!! error TS2322: Type '<S>() => S[]' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2322:   Type '{}[]' is not assignable to type 'T'.
     
     var s = f("str").toUpperCase();
     
diff --git a/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types b/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types
index d6f64bdc933aa..2c1a8177e0b4e 100644
--- a/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types
+++ b/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types
@@ -9,11 +9,11 @@ function f(p: <T>(x: T) => void) { };
 f(x => f(y => x = y));
 >f(x => f(y => x = y)) : void
 >f : (p: <T>(x: T) => void) => void
->x => f(y => x = y) : (x: T) => void
+>x => f(y => x = y) : <T>(x: T) => void
 >x : T
 >f(y => x = y) : void
 >f : (p: <T>(x: T) => void) => void
->y => x = y : (y: T) => T
+>y => x = y : <T>(y: T) => T
 >y : T
 >x = y : T
 >x : T
diff --git a/tests/baselines/reference/genericImplements.errors.txt b/tests/baselines/reference/genericImplements.errors.txt
new file mode 100644
index 0000000000000..7add57989cef3
--- /dev/null
+++ b/tests/baselines/reference/genericImplements.errors.txt
@@ -0,0 +1,32 @@
+tests/cases/compiler/genericImplements.ts(8,7): error TS2420: Class 'X' incorrectly implements interface 'I'.
+  Types of property 'f' are incompatible.
+    Type '<T extends B>() => T' is not assignable to type '<T extends A>() => T'.
+      Type 'B' is not assignable to type 'T'.
+
+
+==== tests/cases/compiler/genericImplements.ts (1 errors) ====
+    class A { a; };
+    class B { b; };
+    interface I {
+        f<T extends A>(): T;
+    } // { f: () => { a; } }
+    
+    // OK
+    class X implements I {  
+          ~
+!!! error TS2420: Class 'X' incorrectly implements interface 'I'.
+!!! error TS2420:   Types of property 'f' are incompatible.
+!!! error TS2420:     Type '<T extends B>() => T' is not assignable to type '<T extends A>() => T'.
+!!! error TS2420:       Type 'B' is not assignable to type 'T'.
+        f<T extends B>(): T { return undefined; }
+    } // { f: () => { b; } }
+    
+    // OK
+    class Y implements I {
+        f<T extends A>(): T { return undefined; }
+    } // { f: () => { a; } }
+    
+    // OK
+    class Z implements I {
+        f<T>(): T { return undefined; }
+    } // { f: <T>() => T } 
\ No newline at end of file
diff --git a/tests/baselines/reference/genericSpecializations1.errors.txt b/tests/baselines/reference/genericSpecializations1.errors.txt
new file mode 100644
index 0000000000000..dd7e540661ee9
--- /dev/null
+++ b/tests/baselines/reference/genericSpecializations1.errors.txt
@@ -0,0 +1,40 @@
+tests/cases/compiler/genericSpecializations1.ts(5,7): error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo<number>'.
+  Types of property 'foo' are incompatible.
+    Type '(x: string) => string' is not assignable to type '<T>(x: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'string'.
+tests/cases/compiler/genericSpecializations1.ts(9,7): error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo<string>'.
+  Types of property 'foo' are incompatible.
+    Type '(x: string) => string' is not assignable to type '<T>(x: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'string'.
+
+
+==== tests/cases/compiler/genericSpecializations1.ts (2 errors) ====
+    interface IFoo<T> {
+        foo<T>(x: T): T; // no error on implementors because IFoo's T is different from foo's T
+    }
+    
+    class IntFooBad implements IFoo<number> {
+          ~~~~~~~~~
+!!! error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo<number>'.
+!!! error TS2420:   Types of property 'foo' are incompatible.
+!!! error TS2420:     Type '(x: string) => string' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2420:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2420:         Type 'T' is not assignable to type 'string'.
+        foo(x: string): string { return null; }
+    }
+    
+    class StringFoo2 implements IFoo<string> {
+          ~~~~~~~~~~
+!!! error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo<string>'.
+!!! error TS2420:   Types of property 'foo' are incompatible.
+!!! error TS2420:     Type '(x: string) => string' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2420:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2420:         Type 'T' is not assignable to type 'string'.
+        foo(x: string): string { return null; }
+    }
+    
+    class StringFoo3 implements IFoo<string> {
+        foo<T>(x: T): T { return null; }
+    }
\ No newline at end of file
diff --git a/tests/baselines/reference/genericSpecializations2.errors.txt b/tests/baselines/reference/genericSpecializations2.errors.txt
index 9d58731b6fb47..e570adb791255 100644
--- a/tests/baselines/reference/genericSpecializations2.errors.txt
+++ b/tests/baselines/reference/genericSpecializations2.errors.txt
@@ -1,8 +1,18 @@
+tests/cases/compiler/genericSpecializations2.ts(7,7): error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo<number>'.
+  Types of property 'foo' are incompatible.
+    Type '<string>(x: string) => string' is not assignable to type '<T>(x: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'string'.
 tests/cases/compiler/genericSpecializations2.ts(8,9): error TS2368: Type parameter name cannot be 'string'.
+tests/cases/compiler/genericSpecializations2.ts(11,7): error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo<string>'.
+  Types of property 'foo' are incompatible.
+    Type '<string>(x: string) => string' is not assignable to type '<T>(x: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'string'.
 tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parameter name cannot be 'string'.
 
 
-==== tests/cases/compiler/genericSpecializations2.ts (2 errors) ====
+==== tests/cases/compiler/genericSpecializations2.ts (4 errors) ====
     class IFoo<T> {
         foo<T>(x: T): T { // no error on implementors because IFoo's T is different from foo's T
             return null;
@@ -10,12 +20,24 @@ tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parame
     }
     
     class IntFooBad implements IFoo<number> {
+          ~~~~~~~~~
+!!! error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo<number>'.
+!!! error TS2420:   Types of property 'foo' are incompatible.
+!!! error TS2420:     Type '<string>(x: string) => string' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2420:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2420:         Type 'T' is not assignable to type 'string'.
         foo<string>(x: string): string { return null; }
             ~~~~~~
 !!! error TS2368: Type parameter name cannot be 'string'.
     }
     
     class StringFoo2 implements IFoo<string> {
+          ~~~~~~~~~~
+!!! error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo<string>'.
+!!! error TS2420:   Types of property 'foo' are incompatible.
+!!! error TS2420:     Type '<string>(x: string) => string' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2420:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2420:         Type 'T' is not assignable to type 'string'.
         foo<string>(x: string): string { return null; }
             ~~~~~~
 !!! error TS2368: Type parameter name cannot be 'string'.
diff --git a/tests/baselines/reference/genericTypeArgumentInference1.errors.txt b/tests/baselines/reference/genericTypeArgumentInference1.errors.txt
new file mode 100644
index 0000000000000..7054967a47587
--- /dev/null
+++ b/tests/baselines/reference/genericTypeArgumentInference1.errors.txt
@@ -0,0 +1,26 @@
+tests/cases/compiler/genericTypeArgumentInference1.ts(12,39): error TS2345: Argument of type '<T>(value: T) => T' is not assignable to parameter of type 'Iterator<string | number | boolean, boolean>'.
+  Type 'string | number | boolean' is not assignable to type 'boolean'.
+    Type 'string' is not assignable to type 'boolean'.
+
+
+==== tests/cases/compiler/genericTypeArgumentInference1.ts (1 errors) ====
+    module Underscore {
+        export interface Iterator<T, U> {
+            (value: T, index: any, list: any): U;
+        }
+        export interface Static {
+            all<T>(list: T[], iterator?: Iterator<T, boolean>, context?: any): T;
+            identity<T>(value: T): T;
+        }
+    }
+    declare var _: Underscore.Static;
+    
+    var r = _.all([true, 1, null, 'yes'], _.identity);
+                                          ~~~~~~~~~~
+!!! error TS2345: Argument of type '<T>(value: T) => T' is not assignable to parameter of type 'Iterator<string | number | boolean, boolean>'.
+!!! error TS2345:   Type 'string | number | boolean' is not assignable to type 'boolean'.
+!!! error TS2345:     Type 'string' is not assignable to type 'boolean'.
+    var r2 = _.all([true], _.identity);
+    var r3 = _.all([], _.identity);
+    var r4 = _.all([<any>true], _.identity);
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/genericTypeAssertions3.types b/tests/baselines/reference/genericTypeAssertions3.types
index e46dd4aaa4e50..2c1eb6b793b30 100644
--- a/tests/baselines/reference/genericTypeAssertions3.types
+++ b/tests/baselines/reference/genericTypeAssertions3.types
@@ -6,8 +6,8 @@ var r = < <T>(x: T) => T > ((x) => { return null; }); // bug was 'could not find
 >x : T
 >T : T
 >T : T
->((x) => { return null; }) : (x: T) => any
->(x) => { return null; } : (x: T) => any
+>((x) => { return null; }) : <T>(x: T) => any
+>(x) => { return null; } : <T>(x: T) => any
 >x : T
 >null : null
 
diff --git a/tests/baselines/reference/implicitAnyGenericTypeInference.types b/tests/baselines/reference/implicitAnyGenericTypeInference.types
index 4124c729f14b1..6ec751130d80f 100644
--- a/tests/baselines/reference/implicitAnyGenericTypeInference.types
+++ b/tests/baselines/reference/implicitAnyGenericTypeInference.types
@@ -18,11 +18,11 @@ var c: Comparer<any>;
 >Comparer : Comparer<T>
 
 c = { compareTo: (x, y) => { return y; } };
->c = { compareTo: (x, y) => { return y; } } : { compareTo: (x: any, y: U) => U; }
+>c = { compareTo: (x, y) => { return y; } } : { compareTo: <U>(x: any, y: U) => U; }
 >c : Comparer<any>
->{ compareTo: (x, y) => { return y; } } : { compareTo: (x: any, y: U) => U; }
->compareTo : (x: any, y: U) => U
->(x, y) => { return y; } : (x: any, y: U) => U
+>{ compareTo: (x, y) => { return y; } } : { compareTo: <U>(x: any, y: U) => U; }
+>compareTo : <U>(x: any, y: U) => U
+>(x, y) => { return y; } : <U>(x: any, y: U) => U
 >x : any
 >y : U
 >y : U
diff --git a/tests/baselines/reference/mismatchedGenericArguments1.errors.txt b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt
new file mode 100644
index 0000000000000..13618c926ef5f
--- /dev/null
+++ b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt
@@ -0,0 +1,40 @@
+tests/cases/compiler/mismatchedGenericArguments1.ts(4,7): error TS2420: Class 'C<T>' incorrectly implements interface 'IFoo<T>'.
+  Types of property 'foo' are incompatible.
+    Type '(x: string) => number' is not assignable to type '<T>(x: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'string'.
+tests/cases/compiler/mismatchedGenericArguments1.ts(10,7): error TS2420: Class 'C2<T>' incorrectly implements interface 'IFoo<T>'.
+  Types of property 'foo' are incompatible.
+    Type '<U>(x: string) => number' is not assignable to type '<T>(x: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'string'.
+
+
+==== tests/cases/compiler/mismatchedGenericArguments1.ts (2 errors) ====
+    interface IFoo<T> {
+       foo<T>(x: T): T;
+    }
+    class C<T> implements IFoo<T> {
+          ~
+!!! error TS2420: Class 'C<T>' incorrectly implements interface 'IFoo<T>'.
+!!! error TS2420:   Types of property 'foo' are incompatible.
+!!! error TS2420:     Type '(x: string) => number' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2420:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2420:         Type 'T' is not assignable to type 'string'.
+       foo(x: string): number {
+         return null;
+       }
+    }
+    
+    class C2<T> implements IFoo<T> {
+          ~~
+!!! error TS2420: Class 'C2<T>' incorrectly implements interface 'IFoo<T>'.
+!!! error TS2420:   Types of property 'foo' are incompatible.
+!!! error TS2420:     Type '<U>(x: string) => number' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2420:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2420:         Type 'T' is not assignable to type 'string'.
+       foo<U>(x: string): number {
+         return null;
+       }
+    }
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/noStrictGenericChecks.js b/tests/baselines/reference/noStrictGenericChecks.js
new file mode 100644
index 0000000000000..485fdc6bd3bc0
--- /dev/null
+++ b/tests/baselines/reference/noStrictGenericChecks.js
@@ -0,0 +1,15 @@
+//// [noStrictGenericChecks.ts]
+type A = <T, U>(x: T, y: U) => [T, U];
+type B = <S>(x: S, y: S) => [S, S];
+
+function f(a: A, b: B) {
+    a = b;  // Error disabled here
+    b = a;  // Ok
+}
+
+
+//// [noStrictGenericChecks.js]
+function f(a, b) {
+    a = b; // Error disabled here
+    b = a; // Ok
+}
diff --git a/tests/baselines/reference/noStrictGenericChecks.symbols b/tests/baselines/reference/noStrictGenericChecks.symbols
new file mode 100644
index 0000000000000..5244cc44f2e93
--- /dev/null
+++ b/tests/baselines/reference/noStrictGenericChecks.symbols
@@ -0,0 +1,38 @@
+=== tests/cases/compiler/noStrictGenericChecks.ts ===
+type A = <T, U>(x: T, y: U) => [T, U];
+>A : Symbol(A, Decl(noStrictGenericChecks.ts, 0, 0))
+>T : Symbol(T, Decl(noStrictGenericChecks.ts, 0, 10))
+>U : Symbol(U, Decl(noStrictGenericChecks.ts, 0, 12))
+>x : Symbol(x, Decl(noStrictGenericChecks.ts, 0, 16))
+>T : Symbol(T, Decl(noStrictGenericChecks.ts, 0, 10))
+>y : Symbol(y, Decl(noStrictGenericChecks.ts, 0, 21))
+>U : Symbol(U, Decl(noStrictGenericChecks.ts, 0, 12))
+>T : Symbol(T, Decl(noStrictGenericChecks.ts, 0, 10))
+>U : Symbol(U, Decl(noStrictGenericChecks.ts, 0, 12))
+
+type B = <S>(x: S, y: S) => [S, S];
+>B : Symbol(B, Decl(noStrictGenericChecks.ts, 0, 38))
+>S : Symbol(S, Decl(noStrictGenericChecks.ts, 1, 10))
+>x : Symbol(x, Decl(noStrictGenericChecks.ts, 1, 13))
+>S : Symbol(S, Decl(noStrictGenericChecks.ts, 1, 10))
+>y : Symbol(y, Decl(noStrictGenericChecks.ts, 1, 18))
+>S : Symbol(S, Decl(noStrictGenericChecks.ts, 1, 10))
+>S : Symbol(S, Decl(noStrictGenericChecks.ts, 1, 10))
+>S : Symbol(S, Decl(noStrictGenericChecks.ts, 1, 10))
+
+function f(a: A, b: B) {
+>f : Symbol(f, Decl(noStrictGenericChecks.ts, 1, 35))
+>a : Symbol(a, Decl(noStrictGenericChecks.ts, 3, 11))
+>A : Symbol(A, Decl(noStrictGenericChecks.ts, 0, 0))
+>b : Symbol(b, Decl(noStrictGenericChecks.ts, 3, 16))
+>B : Symbol(B, Decl(noStrictGenericChecks.ts, 0, 38))
+
+    a = b;  // Error disabled here
+>a : Symbol(a, Decl(noStrictGenericChecks.ts, 3, 11))
+>b : Symbol(b, Decl(noStrictGenericChecks.ts, 3, 16))
+
+    b = a;  // Ok
+>b : Symbol(b, Decl(noStrictGenericChecks.ts, 3, 16))
+>a : Symbol(a, Decl(noStrictGenericChecks.ts, 3, 11))
+}
+
diff --git a/tests/baselines/reference/noStrictGenericChecks.types b/tests/baselines/reference/noStrictGenericChecks.types
new file mode 100644
index 0000000000000..0509c22859a9e
--- /dev/null
+++ b/tests/baselines/reference/noStrictGenericChecks.types
@@ -0,0 +1,40 @@
+=== tests/cases/compiler/noStrictGenericChecks.ts ===
+type A = <T, U>(x: T, y: U) => [T, U];
+>A : A
+>T : T
+>U : U
+>x : T
+>T : T
+>y : U
+>U : U
+>T : T
+>U : U
+
+type B = <S>(x: S, y: S) => [S, S];
+>B : B
+>S : S
+>x : S
+>S : S
+>y : S
+>S : S
+>S : S
+>S : S
+
+function f(a: A, b: B) {
+>f : (a: A, b: B) => void
+>a : A
+>A : A
+>b : B
+>B : B
+
+    a = b;  // Error disabled here
+>a = b : B
+>a : A
+>b : B
+
+    b = a;  // Ok
+>b = a : A
+>b : B
+>a : A
+}
+
diff --git a/tests/baselines/reference/promiseTypeInference.errors.txt b/tests/baselines/reference/promiseTypeInference.errors.txt
new file mode 100644
index 0000000000000..fab56c73375f7
--- /dev/null
+++ b/tests/baselines/reference/promiseTypeInference.errors.txt
@@ -0,0 +1,31 @@
+tests/cases/compiler/promiseTypeInference.ts(10,34): error TS2345: Argument of type '(s: string) => IPromise<number>' is not assignable to parameter of type '(value: string) => number | PromiseLike<number>'.
+  Type 'IPromise<number>' is not assignable to type 'number | PromiseLike<number>'.
+    Type 'IPromise<number>' is not assignable to type 'PromiseLike<number>'.
+      Types of property 'then' are incompatible.
+        Type '<U>(success?: (value: number) => IPromise<U>) => IPromise<U>' is not assignable to type '<TResult1 = number, TResult2 = never>(onfulfilled?: (value: number) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
+          Types of parameters 'success' and 'onfulfilled' are incompatible.
+            Type 'TResult1 | PromiseLike<TResult1>' is not assignable to type 'IPromise<TResult1 | TResult2>'.
+              Type 'TResult1' is not assignable to type 'IPromise<TResult1 | TResult2>'.
+
+
+==== tests/cases/compiler/promiseTypeInference.ts (1 errors) ====
+    declare class Promise<T> {
+        then<U>(success?: (value: T) => Promise<U>): Promise<U>;
+    }
+    interface IPromise<T> {
+        then<U>(success?: (value: T) => IPromise<U>): IPromise<U>;
+    }
+    declare function load(name: string): Promise<string>;
+    declare function convert(s: string): IPromise<number>;
+    
+    var $$x = load("something").then(s => convert(s));
+                                     ~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '(s: string) => IPromise<number>' is not assignable to parameter of type '(value: string) => number | PromiseLike<number>'.
+!!! error TS2345:   Type 'IPromise<number>' is not assignable to type 'number | PromiseLike<number>'.
+!!! error TS2345:     Type 'IPromise<number>' is not assignable to type 'PromiseLike<number>'.
+!!! error TS2345:       Types of property 'then' are incompatible.
+!!! error TS2345:         Type '<U>(success?: (value: number) => IPromise<U>) => IPromise<U>' is not assignable to type '<TResult1 = number, TResult2 = never>(onfulfilled?: (value: number) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
+!!! error TS2345:           Types of parameters 'success' and 'onfulfilled' are incompatible.
+!!! error TS2345:             Type 'TResult1 | PromiseLike<TResult1>' is not assignable to type 'IPromise<TResult1 | TResult2>'.
+!!! error TS2345:               Type 'TResult1' is not assignable to type 'IPromise<TResult1 | TResult2>'.
+    
\ No newline at end of file
diff --git a/tests/baselines/reference/subtypingWithCallSignatures2.types b/tests/baselines/reference/subtypingWithCallSignatures2.types
index 86c65702b985c..029262380d89a 100644
--- a/tests/baselines/reference/subtypingWithCallSignatures2.types
+++ b/tests/baselines/reference/subtypingWithCallSignatures2.types
@@ -325,20 +325,20 @@ var r1arg2 = (x: number) => [1];
 >1 : 1
 
 var r1 = foo1(r1arg1); // any, return types are not subtype of first overload
->r1 : any
->foo1(r1arg1) : any
+>r1 : (x: number) => number[]
+>foo1(r1arg1) : (x: number) => number[]
 >foo1 : { (a: (x: number) => number[]): (x: number) => number[]; (a: any): any; }
 >r1arg1 : <T>(x: T) => T[]
 
 var r1a = [r1arg2, r1arg1]; // generic signature, subtype in both directions
->r1a : (<T>(x: T) => T[])[]
->[r1arg2, r1arg1] : (<T>(x: T) => T[])[]
+>r1a : ((x: number) => number[])[]
+>[r1arg2, r1arg1] : ((x: number) => number[])[]
 >r1arg2 : (x: number) => number[]
 >r1arg1 : <T>(x: T) => T[]
 
 var r1b = [r1arg1, r1arg2]; // generic signature, subtype in both directions
->r1b : (<T>(x: T) => T[])[]
->[r1arg1, r1arg2] : (<T>(x: T) => T[])[]
+>r1b : ((x: number) => number[])[]
+>[r1arg1, r1arg2] : ((x: number) => number[])[]
 >r1arg1 : <T>(x: T) => T[]
 >r1arg2 : (x: number) => number[]
 
@@ -365,14 +365,14 @@ var r2 = foo2(r2arg1);
 >r2arg1 : <T>(x: T) => string[]
 
 var r2a = [r2arg1, r2arg2];
->r2a : (<T>(x: T) => string[])[]
->[r2arg1, r2arg2] : (<T>(x: T) => string[])[]
+>r2a : ((x: number) => string[])[]
+>[r2arg1, r2arg2] : ((x: number) => string[])[]
 >r2arg1 : <T>(x: T) => string[]
 >r2arg2 : (x: number) => string[]
 
 var r2b = [r2arg2, r2arg1];
->r2b : (<T>(x: T) => string[])[]
->[r2arg2, r2arg1] : (<T>(x: T) => string[])[]
+>r2b : ((x: number) => string[])[]
+>[r2arg2, r2arg1] : ((x: number) => string[])[]
 >r2arg2 : (x: number) => string[]
 >r2arg1 : <T>(x: T) => string[]
 
@@ -396,14 +396,14 @@ var r3 = foo3(r3arg1);
 >r3arg1 : <T>(x: T) => T
 
 var r3a = [r3arg1, r3arg2];
->r3a : (<T>(x: T) => T)[]
->[r3arg1, r3arg2] : (<T>(x: T) => T)[]
+>r3a : ((x: number) => void)[]
+>[r3arg1, r3arg2] : ((x: number) => void)[]
 >r3arg1 : <T>(x: T) => T
 >r3arg2 : (x: number) => void
 
 var r3b = [r3arg2, r3arg1];
->r3b : (<T>(x: T) => T)[]
->[r3arg2, r3arg1] : (<T>(x: T) => T)[]
+>r3b : ((x: number) => void)[]
+>[r3arg2, r3arg1] : ((x: number) => void)[]
 >r3arg2 : (x: number) => void
 >r3arg1 : <T>(x: T) => T
 
@@ -426,20 +426,20 @@ var r4arg2 = (x: string, y: number) => '';
 >'' : ""
 
 var r4 = foo4(r4arg1); // any
->r4 : any
->foo4(r4arg1) : any
+>r4 : (x: string, y: number) => string
+>foo4(r4arg1) : (x: string, y: number) => string
 >foo4 : { (a: (x: string, y: number) => string): (x: string, y: number) => string; (a: any): any; }
 >r4arg1 : <T, U>(x: T, y: U) => T
 
 var r4a = [r4arg1, r4arg2];
->r4a : (<T, U>(x: T, y: U) => T)[]
->[r4arg1, r4arg2] : (<T, U>(x: T, y: U) => T)[]
+>r4a : ((x: string, y: number) => string)[]
+>[r4arg1, r4arg2] : ((x: string, y: number) => string)[]
 >r4arg1 : <T, U>(x: T, y: U) => T
 >r4arg2 : (x: string, y: number) => string
 
 var r4b = [r4arg2, r4arg1];
->r4b : (<T, U>(x: T, y: U) => T)[]
->[r4arg2, r4arg1] : (<T, U>(x: T, y: U) => T)[]
+>r4b : ((x: string, y: number) => string)[]
+>[r4arg2, r4arg1] : ((x: string, y: number) => string)[]
 >r4arg2 : (x: string, y: number) => string
 >r4arg1 : <T, U>(x: T, y: U) => T
 
@@ -464,20 +464,20 @@ var r5arg2 = (x: (arg: string) => number) => '';
 >'' : ""
 
 var r5 = foo5(r5arg1); // any
->r5 : any
->foo5(r5arg1) : any
+>r5 : (x: (arg: string) => number) => string
+>foo5(r5arg1) : (x: (arg: string) => number) => string
 >foo5 : { (a: (x: (arg: string) => number) => string): (x: (arg: string) => number) => string; (a: any): any; }
 >r5arg1 : <T, U>(x: (arg: T) => U) => T
 
 var r5a = [r5arg1, r5arg2];
->r5a : (<T, U>(x: (arg: T) => U) => T)[]
->[r5arg1, r5arg2] : (<T, U>(x: (arg: T) => U) => T)[]
+>r5a : ((x: (arg: string) => number) => string)[]
+>[r5arg1, r5arg2] : ((x: (arg: string) => number) => string)[]
 >r5arg1 : <T, U>(x: (arg: T) => U) => T
 >r5arg2 : (x: (arg: string) => number) => string
 
 var r5b = [r5arg2, r5arg1];
->r5b : (<T, U>(x: (arg: T) => U) => T)[]
->[r5arg2, r5arg1] : (<T, U>(x: (arg: T) => U) => T)[]
+>r5b : ((x: (arg: string) => number) => string)[]
+>[r5arg2, r5arg1] : ((x: (arg: string) => number) => string)[]
 >r5arg2 : (x: (arg: string) => number) => string
 >r5arg1 : <T, U>(x: (arg: T) => U) => T
 
@@ -508,20 +508,20 @@ var r6arg2 = (x: (arg: Base) => Derived) => <Base>null;
 >null : null
 
 var r6 = foo6(r6arg1); // any
->r6 : any
->foo6(r6arg1) : any
+>r6 : (x: (arg: Base) => Derived) => Base
+>foo6(r6arg1) : (x: (arg: Base) => Derived) => Base
 >foo6 : { (a: (x: (arg: Base) => Derived) => Base): (x: (arg: Base) => Derived) => Base; (a: any): any; }
 >r6arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U) => T
 
 var r6a = [r6arg1, r6arg2];
->r6a : (<T extends Base, U extends Derived>(x: (arg: T) => U) => T)[]
->[r6arg1, r6arg2] : (<T extends Base, U extends Derived>(x: (arg: T) => U) => T)[]
+>r6a : ((x: (arg: Base) => Derived) => Base)[]
+>[r6arg1, r6arg2] : ((x: (arg: Base) => Derived) => Base)[]
 >r6arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U) => T
 >r6arg2 : (x: (arg: Base) => Derived) => Base
 
 var r6b = [r6arg2, r6arg1];
->r6b : (<T extends Base, U extends Derived>(x: (arg: T) => U) => T)[]
->[r6arg2, r6arg1] : (<T extends Base, U extends Derived>(x: (arg: T) => U) => T)[]
+>r6b : ((x: (arg: Base) => Derived) => Base)[]
+>[r6arg2, r6arg1] : ((x: (arg: Base) => Derived) => Base)[]
 >r6arg2 : (x: (arg: Base) => Derived) => Base
 >r6arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U) => T
 
@@ -558,20 +558,20 @@ var r7arg2 = (x: (arg: Base) => Derived) => (r: Base) => <Derived>null;
 >null : null
 
 var r7 = foo7(r7arg1); // any
->r7 : any
->foo7(r7arg1) : any
+>r7 : (x: (arg: Base) => Derived) => (r: Base) => Derived
+>foo7(r7arg1) : (x: (arg: Base) => Derived) => (r: Base) => Derived
 >foo7 : { (a: (x: (arg: Base) => Derived) => (r: Base) => Derived): (x: (arg: Base) => Derived) => (r: Base) => Derived; (a: any): any; }
 >r7arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U
 
 var r7a = [r7arg1, r7arg2];
->r7a : (<T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U)[]
->[r7arg1, r7arg2] : (<T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U)[]
+>r7a : ((x: (arg: Base) => Derived) => (r: Base) => Derived)[]
+>[r7arg1, r7arg2] : ((x: (arg: Base) => Derived) => (r: Base) => Derived)[]
 >r7arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U
 >r7arg2 : (x: (arg: Base) => Derived) => (r: Base) => Derived
 
 var r7b = [r7arg2, r7arg1];
->r7b : (<T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U)[]
->[r7arg2, r7arg1] : (<T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U)[]
+>r7b : ((x: (arg: Base) => Derived) => (r: Base) => Derived)[]
+>[r7arg2, r7arg1] : ((x: (arg: Base) => Derived) => (r: Base) => Derived)[]
 >r7arg2 : (x: (arg: Base) => Derived) => (r: Base) => Derived
 >r7arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U
 
@@ -616,20 +616,20 @@ var r8arg2 = (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base
 >null : null
 
 var r8 = foo8(r8arg1); // any
->r8 : any
->foo8(r8arg1) : any
+>r8 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived
+>foo8(r8arg1) : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived
 >foo8 : { (a: (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived): (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived; (a: any): any; }
 >r8arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U
 
 var r8a = [r8arg1, r8arg2];
->r8a : (<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U)[]
->[r8arg1, r8arg2] : (<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U)[]
+>r8a : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[]
+>[r8arg1, r8arg2] : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[]
 >r8arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U
 >r8arg2 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived
 
 var r8b = [r8arg2, r8arg1];
->r8b : (<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U)[]
->[r8arg2, r8arg1] : (<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U)[]
+>r8b : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[]
+>[r8arg2, r8arg1] : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[]
 >r8arg2 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived
 >r8arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U
 
@@ -675,20 +675,20 @@ var r9arg2 = (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base
 >null : null
 
 var r9 = foo9(r9arg1); // any
->r9 : any
->foo9(r9arg1) : any
+>r9 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived
+>foo9(r9arg1) : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived
 >foo9 : { (a: (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived): (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived; (a: any): any; }
 >r9arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U
 
 var r9a = [r9arg1, r9arg2];
->r9a : ((<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U) | ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived))[]
->[r9arg1, r9arg2] : ((<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U) | ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived))[]
+>r9a : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[]
+>[r9arg1, r9arg2] : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[]
 >r9arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U
 >r9arg2 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived
 
 var r9b = [r9arg2, r9arg1];
->r9b : ((<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U) | ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived))[]
->[r9arg2, r9arg1] : ((<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U) | ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived))[]
+>r9b : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[]
+>[r9arg2, r9arg1] : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[]
 >r9arg2 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived
 >r9arg1 : <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U
 
@@ -713,20 +713,20 @@ var r10arg2 = (...x: Derived[]) => <Derived>null;
 >null : null
 
 var r10 = foo10(r10arg1); // any
->r10 : any
->foo10(r10arg1) : any
+>r10 : (...x: Derived[]) => Derived
+>foo10(r10arg1) : (...x: Derived[]) => Derived
 >foo10 : { (a: (...x: Derived[]) => Derived): (...x: Derived[]) => Derived; (a: any): any; }
 >r10arg1 : <T extends Derived>(...x: T[]) => T
 
 var r10a = [r10arg1, r10arg2];
->r10a : (<T extends Derived>(...x: T[]) => T)[]
->[r10arg1, r10arg2] : (<T extends Derived>(...x: T[]) => T)[]
+>r10a : ((...x: Derived[]) => Derived)[]
+>[r10arg1, r10arg2] : ((...x: Derived[]) => Derived)[]
 >r10arg1 : <T extends Derived>(...x: T[]) => T
 >r10arg2 : (...x: Derived[]) => Derived
 
 var r10b = [r10arg2, r10arg1];
->r10b : (<T extends Derived>(...x: T[]) => T)[]
->[r10arg2, r10arg1] : (<T extends Derived>(...x: T[]) => T)[]
+>r10b : ((...x: Derived[]) => Derived)[]
+>[r10arg2, r10arg1] : ((...x: Derived[]) => Derived)[]
 >r10arg2 : (...x: Derived[]) => Derived
 >r10arg1 : <T extends Derived>(...x: T[]) => T
 
@@ -754,20 +754,20 @@ var r11arg2 = (x: { foo: string }, y: { foo: string; bar: string }) => <Base>nul
 >null : null
 
 var r11 = foo11(r11arg1); // any
->r11 : any
->foo11(r11arg1) : any
+>r11 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
+>foo11(r11arg1) : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 >foo11 : { (a: (x: { foo: string; }, y: { foo: string; bar: string; }) => Base): (x: { foo: string; }, y: { foo: string; bar: string; }) => Base; (a: any): any; }
 >r11arg1 : <T extends Base>(x: T, y: T) => T
 
 var r11a = [r11arg1, r11arg2];
->r11a : (<T extends Base>(x: T, y: T) => T)[]
->[r11arg1, r11arg2] : (<T extends Base>(x: T, y: T) => T)[]
+>r11a : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
+>[r11arg1, r11arg2] : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
 >r11arg1 : <T extends Base>(x: T, y: T) => T
 >r11arg2 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 
 var r11b = [r11arg2, r11arg1];
->r11b : (<T extends Base>(x: T, y: T) => T)[]
->[r11arg2, r11arg1] : (<T extends Base>(x: T, y: T) => T)[]
+>r11b : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
+>[r11arg2, r11arg1] : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
 >r11arg2 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 >r11arg1 : <T extends Base>(x: T, y: T) => T
 
@@ -808,14 +808,14 @@ var r12 = foo12(r12arg1); // any
 >r12arg1 : <T extends Base[]>(x: Base[], y: T) => Derived[]
 
 var r12a = [r12arg1, r12arg2];
->r12a : (<T extends Base[]>(x: Base[], y: T) => Derived[])[]
->[r12arg1, r12arg2] : (<T extends Base[]>(x: Base[], y: T) => Derived[])[]
+>r12a : ((x: Base[], y: Derived2[]) => Derived[])[]
+>[r12arg1, r12arg2] : ((x: Base[], y: Derived2[]) => Derived[])[]
 >r12arg1 : <T extends Base[]>(x: Base[], y: T) => Derived[]
 >r12arg2 : (x: Base[], y: Derived2[]) => Derived[]
 
 var r12b = [r12arg2, r12arg1];
->r12b : (<T extends Base[]>(x: Base[], y: T) => Derived[])[]
->[r12arg2, r12arg1] : (<T extends Base[]>(x: Base[], y: T) => Derived[])[]
+>r12b : ((x: Base[], y: Derived2[]) => Derived[])[]
+>[r12arg2, r12arg1] : ((x: Base[], y: Derived2[]) => Derived[])[]
 >r12arg2 : (x: Base[], y: Derived2[]) => Derived[]
 >r12arg1 : <T extends Base[]>(x: Base[], y: T) => Derived[]
 
@@ -847,20 +847,20 @@ var r13arg2 = (x: Array<Base>, y: Array<Derived>) => <Array<Derived>>null;
 >null : null
 
 var r13 = foo13(r13arg1); // any
->r13 : any
->foo13(r13arg1) : any
+>r13 : (x: Base[], y: Derived[]) => Derived[]
+>foo13(r13arg1) : (x: Base[], y: Derived[]) => Derived[]
 >foo13 : { (a: (x: Base[], y: Derived[]) => Derived[]): (x: Base[], y: Derived[]) => Derived[]; (a: any): any; }
 >r13arg1 : <T extends Derived[]>(x: Base[], y: T) => T
 
 var r13a = [r13arg1, r13arg2];
->r13a : (<T extends Derived[]>(x: Base[], y: T) => T)[]
->[r13arg1, r13arg2] : (<T extends Derived[]>(x: Base[], y: T) => T)[]
+>r13a : ((x: Base[], y: Derived[]) => Derived[])[]
+>[r13arg1, r13arg2] : ((x: Base[], y: Derived[]) => Derived[])[]
 >r13arg1 : <T extends Derived[]>(x: Base[], y: T) => T
 >r13arg2 : (x: Base[], y: Derived[]) => Derived[]
 
 var r13b = [r13arg2, r13arg1];
->r13b : (<T extends Derived[]>(x: Base[], y: T) => T)[]
->[r13arg2, r13arg1] : (<T extends Derived[]>(x: Base[], y: T) => T)[]
+>r13b : ((x: Base[], y: Derived[]) => Derived[])[]
+>[r13arg2, r13arg1] : ((x: Base[], y: Derived[]) => Derived[])[]
 >r13arg2 : (x: Base[], y: Derived[]) => Derived[]
 >r13arg1 : <T extends Derived[]>(x: Base[], y: T) => T
 
@@ -888,20 +888,20 @@ var r14arg2 = (x: { a: string; b: number }) => <Object>null;
 >null : null
 
 var r14 = foo14(r14arg1); // any
->r14 : any
->foo14(r14arg1) : any
+>r14 : (x: { a: string; b: number; }) => Object
+>foo14(r14arg1) : (x: { a: string; b: number; }) => Object
 >foo14 : { (a: (x: { a: string; b: number; }) => Object): (x: { a: string; b: number; }) => Object; (a: any): any; }
 >r14arg1 : <T>(x: { a: T; b: T; }) => T
 
 var r14a = [r14arg1, r14arg2];
->r14a : (<T>(x: { a: T; b: T; }) => T)[]
->[r14arg1, r14arg2] : (<T>(x: { a: T; b: T; }) => T)[]
+>r14a : ((x: { a: string; b: number; }) => Object)[]
+>[r14arg1, r14arg2] : ((x: { a: string; b: number; }) => Object)[]
 >r14arg1 : <T>(x: { a: T; b: T; }) => T
 >r14arg2 : (x: { a: string; b: number; }) => Object
 
 var r14b = [r14arg2, r14arg1];
->r14b : (<T>(x: { a: T; b: T; }) => T)[]
->[r14arg2, r14arg1] : (<T>(x: { a: T; b: T; }) => T)[]
+>r14b : ((x: { a: string; b: number; }) => Object)[]
+>[r14arg2, r14arg1] : ((x: { a: string; b: number; }) => Object)[]
 >r14arg2 : (x: { a: string; b: number; }) => Object
 >r14arg1 : <T>(x: { a: T; b: T; }) => T
 
diff --git a/tests/baselines/reference/subtypingWithCallSignatures3.types b/tests/baselines/reference/subtypingWithCallSignatures3.types
index 6abc7567efb2c..99953d899f2f6 100644
--- a/tests/baselines/reference/subtypingWithCallSignatures3.types
+++ b/tests/baselines/reference/subtypingWithCallSignatures3.types
@@ -206,8 +206,8 @@ module Errors {
 >a2 : any
 
     var r1 = foo2(<T, U>(x: T) => <U[]>null); // any
->r1 : any
->foo2(<T, U>(x: T) => <U[]>null) : any
+>r1 : (x: number) => string[]
+>foo2(<T, U>(x: T) => <U[]>null) : (x: number) => string[]
 >foo2 : { (a2: (x: number) => string[]): (x: number) => string[]; (a2: any): any; }
 ><T, U>(x: T) => <U[]>null : <T, U>(x: T) => U[]
 >T : T
@@ -219,8 +219,8 @@ module Errors {
 >null : null
 
     var r1a = [(x: number) => [''], <T, U>(x: T) => <U[]>null];
->r1a : (<T, U>(x: T) => U[])[]
->[(x: number) => [''], <T, U>(x: T) => <U[]>null] : (<T, U>(x: T) => U[])[]
+>r1a : ((x: number) => string[])[]
+>[(x: number) => [''], <T, U>(x: T) => <U[]>null] : ((x: number) => string[])[]
 >(x: number) => [''] : (x: number) => string[]
 >x : number
 >[''] : string[]
@@ -235,8 +235,8 @@ module Errors {
 >null : null
 
     var r1b = [<T, U>(x: T) => <U[]>null, (x: number) => ['']];
->r1b : (<T, U>(x: T) => U[])[]
->[<T, U>(x: T) => <U[]>null, (x: number) => ['']] : (<T, U>(x: T) => U[])[]
+>r1b : ((x: number) => string[])[]
+>[<T, U>(x: T) => <U[]>null, (x: number) => ['']] : ((x: number) => string[])[]
 ><T, U>(x: T) => <U[]>null : <T, U>(x: T) => U[]
 >T : T
 >U : U
@@ -285,20 +285,20 @@ module Errors {
 >null : null
 
     var r2 = foo7(r2arg); // any
->r2 : any
->foo7(r2arg) : any
+>r2 : (x: (arg: Base) => Derived) => (r: Base) => Derived2
+>foo7(r2arg) : (x: (arg: Base) => Derived) => (r: Base) => Derived2
 >foo7 : { (a2: (x: (arg: Base) => Derived) => (r: Base) => Derived2): (x: (arg: Base) => Derived) => (r: Base) => Derived2; (a2: any): any; }
 >r2arg : <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V
 
     var r2a = [r2arg2, r2arg];
->r2a : (<T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V)[]
->[r2arg2, r2arg] : (<T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V)[]
+>r2a : ((x: (arg: Base) => Derived) => (r: Base) => Derived2)[]
+>[r2arg2, r2arg] : ((x: (arg: Base) => Derived) => (r: Base) => Derived2)[]
 >r2arg2 : (x: (arg: Base) => Derived) => (r: Base) => Derived2
 >r2arg : <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V
 
     var r2b = [r2arg, r2arg2];
->r2b : (<T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V)[]
->[r2arg, r2arg2] : (<T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V)[]
+>r2b : ((x: (arg: Base) => Derived) => (r: Base) => Derived2)[]
+>[r2arg, r2arg2] : ((x: (arg: Base) => Derived) => (r: Base) => Derived2)[]
 >r2arg : <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V
 >r2arg2 : (x: (arg: Base) => Derived) => (r: Base) => Derived2
 
@@ -381,20 +381,20 @@ module Errors {
 >null : null
 
     var r4 = foo10(r4arg); // any
->r4 : any
->foo10(r4arg) : any
+>r4 : (...x: Base[]) => Base
+>foo10(r4arg) : (...x: Base[]) => Base
 >foo10 : { (a2: (...x: Base[]) => Base): (...x: Base[]) => Base; (a2: any): any; }
 >r4arg : <T extends Derived>(...x: T[]) => T
 
     var r4a = [r4arg2, r4arg];
->r4a : (<T extends Derived>(...x: T[]) => T)[]
->[r4arg2, r4arg] : (<T extends Derived>(...x: T[]) => T)[]
+>r4a : ((...x: Base[]) => Base)[]
+>[r4arg2, r4arg] : ((...x: Base[]) => Base)[]
 >r4arg2 : (...x: Base[]) => Base
 >r4arg : <T extends Derived>(...x: T[]) => T
 
     var r4b = [r4arg, r4arg2];
->r4b : (<T extends Derived>(...x: T[]) => T)[]
->[r4arg, r4arg2] : (<T extends Derived>(...x: T[]) => T)[]
+>r4b : ((...x: Base[]) => Base)[]
+>[r4arg, r4arg2] : ((...x: Base[]) => Base)[]
 >r4arg : <T extends Derived>(...x: T[]) => T
 >r4arg2 : (...x: Base[]) => Base
 
@@ -424,20 +424,20 @@ module Errors {
 >null : null
 
     var r5 = foo11(r5arg); // any
->r5 : any
->foo11(r5arg) : any
+>r5 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
+>foo11(r5arg) : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 >foo11 : { (a2: (x: { foo: string; }, y: { foo: string; bar: string; }) => Base): (x: { foo: string; }, y: { foo: string; bar: string; }) => Base; (a2: any): any; }
 >r5arg : <T extends Derived>(x: T, y: T) => T
 
     var r5a = [r5arg2, r5arg];
->r5a : (<T extends Derived>(x: T, y: T) => T)[]
->[r5arg2, r5arg] : (<T extends Derived>(x: T, y: T) => T)[]
+>r5a : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
+>[r5arg2, r5arg] : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
 >r5arg2 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 >r5arg : <T extends Derived>(x: T, y: T) => T
 
     var r5b = [r5arg, r5arg2];
->r5b : (<T extends Derived>(x: T, y: T) => T)[]
->[r5arg, r5arg2] : (<T extends Derived>(x: T, y: T) => T)[]
+>r5b : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
+>[r5arg, r5arg2] : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
 >r5arg : <T extends Derived>(x: T, y: T) => T
 >r5arg2 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 
@@ -478,14 +478,14 @@ module Errors {
 >r6arg : (x: Base[], y: Derived2[]) => Derived[]
 
     var r6a = [r6arg2, r6arg];
->r6a : (<T extends Derived2[]>(x: Base[], y: Base[]) => T)[]
->[r6arg2, r6arg] : (<T extends Derived2[]>(x: Base[], y: Base[]) => T)[]
+>r6a : ((x: Base[], y: Derived2[]) => Derived[])[]
+>[r6arg2, r6arg] : ((x: Base[], y: Derived2[]) => Derived[])[]
 >r6arg2 : <T extends Derived2[]>(x: Base[], y: Base[]) => T
 >r6arg : (x: Base[], y: Derived2[]) => Derived[]
 
     var r6b = [r6arg, r6arg2];
->r6b : (<T extends Derived2[]>(x: Base[], y: Base[]) => T)[]
->[r6arg, r6arg2] : (<T extends Derived2[]>(x: Base[], y: Base[]) => T)[]
+>r6b : ((x: Base[], y: Derived2[]) => Derived[])[]
+>[r6arg, r6arg2] : ((x: Base[], y: Derived2[]) => Derived[])[]
 >r6arg : (x: Base[], y: Derived2[]) => Derived[]
 >r6arg2 : <T extends Derived2[]>(x: Base[], y: Base[]) => T
 
@@ -517,14 +517,14 @@ module Errors {
 >r7arg : <T>(x: { a: T; b: T; }) => T
 
     var r7a = [r7arg2, r7arg];
->r7a : (<T>(x: { a: T; b: T; }) => T)[]
->[r7arg2, r7arg] : (<T>(x: { a: T; b: T; }) => T)[]
+>r7a : ((<T>(x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => number))[]
+>[r7arg2, r7arg] : ((<T>(x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => number))[]
 >r7arg2 : (x: { a: string; b: number; }) => number
 >r7arg : <T>(x: { a: T; b: T; }) => T
 
     var r7b = [r7arg, r7arg2];
->r7b : (<T>(x: { a: T; b: T; }) => T)[]
->[r7arg, r7arg2] : (<T>(x: { a: T; b: T; }) => T)[]
+>r7b : ((<T>(x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => number))[]
+>[r7arg, r7arg2] : ((<T>(x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => number))[]
 >r7arg : <T>(x: { a: T; b: T; }) => T
 >r7arg2 : (x: { a: string; b: number; }) => number
 
@@ -541,20 +541,20 @@ module Errors {
 >1 : 1
 
     var r7c = foo15(r7arg3); // (x: { a: string; b: number }) => number): number;
->r7c : (x: { a: string; b: number; }) => number
->foo15(r7arg3) : (x: { a: string; b: number; }) => number
+>r7c : any
+>foo15(r7arg3) : any
 >foo15 : { (a2: (x: { a: string; b: number; }) => number): (x: { a: string; b: number; }) => number; (a2: any): any; }
 >r7arg3 : <T extends Base>(x: { a: T; b: T; }) => number
 
     var r7d = [r7arg2, r7arg3];
->r7d : ((x: { a: string; b: number; }) => number)[]
->[r7arg2, r7arg3] : ((x: { a: string; b: number; }) => number)[]
+>r7d : (((x: { a: string; b: number; }) => number) | (<T extends Base>(x: { a: T; b: T; }) => number))[]
+>[r7arg2, r7arg3] : (((x: { a: string; b: number; }) => number) | (<T extends Base>(x: { a: T; b: T; }) => number))[]
 >r7arg2 : (x: { a: string; b: number; }) => number
 >r7arg3 : <T extends Base>(x: { a: T; b: T; }) => number
 
     var r7e = [r7arg3, r7arg2];
->r7e : ((x: { a: string; b: number; }) => number)[]
->[r7arg3, r7arg2] : ((x: { a: string; b: number; }) => number)[]
+>r7e : (((x: { a: string; b: number; }) => number) | (<T extends Base>(x: { a: T; b: T; }) => number))[]
+>[r7arg3, r7arg2] : (((x: { a: string; b: number; }) => number) | (<T extends Base>(x: { a: T; b: T; }) => number))[]
 >r7arg3 : <T extends Base>(x: { a: T; b: T; }) => number
 >r7arg2 : (x: { a: string; b: number; }) => number
 
@@ -620,8 +620,8 @@ module WithGenericSignaturesInBaseType {
 >'' : ""
 
     var r2 = foo2(r2arg2); // <T>(x:T) => T[] since we can infer from generic signatures now
->r2 : <T>(x: T) => T[]
->foo2(r2arg2) : <T>(x: T) => T[]
+>r2 : any
+>foo2(r2arg2) : any
 >foo2 : { (a2: <T>(x: T) => T[]): <T>(x: T) => T[]; (a2: any): any; }
 >r2arg2 : <T>(x: T) => string[]
 
diff --git a/tests/baselines/reference/subtypingWithCallSignatures4.types b/tests/baselines/reference/subtypingWithCallSignatures4.types
index 5926636289abc..3751b9c73dd99 100644
--- a/tests/baselines/reference/subtypingWithCallSignatures4.types
+++ b/tests/baselines/reference/subtypingWithCallSignatures4.types
@@ -317,14 +317,14 @@ var r3 = foo3(r3arg);
 >r3arg : <T>(x: T) => T
 
 var r3a = [r3arg, r3arg2];
->r3a : (<T>(x: T) => T)[]
->[r3arg, r3arg2] : (<T>(x: T) => T)[]
+>r3a : (<T>(x: T) => void)[]
+>[r3arg, r3arg2] : (<T>(x: T) => void)[]
 >r3arg : <T>(x: T) => T
 >r3arg2 : <T>(x: T) => void
 
 var r3b = [r3arg2, r3arg];
->r3b : (<T>(x: T) => T)[]
->[r3arg2, r3arg] : (<T>(x: T) => T)[]
+>r3b : (<T>(x: T) => void)[]
+>[r3arg2, r3arg] : (<T>(x: T) => void)[]
 >r3arg2 : <T>(x: T) => void
 >r3arg : <T>(x: T) => T
 
@@ -543,14 +543,14 @@ var r15 = foo15(r15arg);
 >r15arg : <U, V>(x: { a: U; b: V; }) => U[]
 
 var r15a = [r15arg, r15arg2];
->r15a : (<U, V>(x: { a: U; b: V; }) => U[])[]
->[r15arg, r15arg2] : (<U, V>(x: { a: U; b: V; }) => U[])[]
+>r15a : (<T>(x: { a: T; b: T; }) => T[])[]
+>[r15arg, r15arg2] : (<T>(x: { a: T; b: T; }) => T[])[]
 >r15arg : <U, V>(x: { a: U; b: V; }) => U[]
 >r15arg2 : <T>(x: { a: T; b: T; }) => T[]
 
 var r15b = [r15arg2, r15arg];
->r15b : (<U, V>(x: { a: U; b: V; }) => U[])[]
->[r15arg2, r15arg] : (<U, V>(x: { a: U; b: V; }) => U[])[]
+>r15b : (<T>(x: { a: T; b: T; }) => T[])[]
+>[r15arg2, r15arg] : (<T>(x: { a: T; b: T; }) => T[])[]
 >r15arg2 : <T>(x: { a: T; b: T; }) => T[]
 >r15arg : <U, V>(x: { a: U; b: V; }) => U[]
 
diff --git a/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt b/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt
index da742fcd69cbd..b17196896067d 100644
--- a/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt
+++ b/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt
@@ -2,9 +2,13 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
   Types of property 'a' are incompatible.
     Type '(x: string) => string' is not assignable to type '{ (x: "a"): number; (x: string): number; }'.
       Type 'string' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithSpecializedSignatures.ts(76,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
+  Types of property 'a2' are incompatible.
+    Type '<T>(x: T) => string' is not assignable to type '<T>(x: T) => T'.
+      Type 'string' is not assignable to type 'T'.
 
 
-==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithSpecializedSignatures.ts (1 errors) ====
+==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithSpecializedSignatures.ts (2 errors) ====
     // same as subtypingWithCallSignatures but with additional specialized signatures that should not affect the results
     
     module CallSignature {
@@ -86,6 +90,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
     
         // S's
         interface I3 extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type '<T>(x: T) => string' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2430:       Type 'string' is not assignable to type 'T'.
             // N's
             a2: <T>(x: T) => string; // error because base returns non-void;
         }
diff --git a/tests/baselines/reference/subtypingWithConstructSignatures2.types b/tests/baselines/reference/subtypingWithConstructSignatures2.types
index d723a367ecb3d..9bf8c58edb6f3 100644
--- a/tests/baselines/reference/subtypingWithConstructSignatures2.types
+++ b/tests/baselines/reference/subtypingWithConstructSignatures2.types
@@ -320,20 +320,20 @@ var r1arg2: new (x: number) => number[];
 >x : number
 
 var r1 = foo1(r1arg1); // any, return types are not subtype of first overload
->r1 : any
->foo1(r1arg1) : any
+>r1 : new (x: number) => number[]
+>foo1(r1arg1) : new (x: number) => number[]
 >foo1 : { (a: new (x: number) => number[]): new (x: number) => number[]; (a: any): any; }
 >r1arg1 : new <T>(x: T) => T[]
 
 var r1a = [r1arg2, r1arg1]; // generic signature, subtype in both directions
->r1a : (new <T>(x: T) => T[])[]
->[r1arg2, r1arg1] : (new <T>(x: T) => T[])[]
+>r1a : (new (x: number) => number[])[]
+>[r1arg2, r1arg1] : (new (x: number) => number[])[]
 >r1arg2 : new (x: number) => number[]
 >r1arg1 : new <T>(x: T) => T[]
 
 var r1b = [r1arg1, r1arg2]; // generic signature, subtype in both directions
->r1b : (new <T>(x: T) => T[])[]
->[r1arg1, r1arg2] : (new <T>(x: T) => T[])[]
+>r1b : (new (x: number) => number[])[]
+>[r1arg1, r1arg2] : (new (x: number) => number[])[]
 >r1arg1 : new <T>(x: T) => T[]
 >r1arg2 : new (x: number) => number[]
 
@@ -354,14 +354,14 @@ var r2 = foo2(r2arg1);
 >r2arg1 : new <T>(x: T) => string[]
 
 var r2a = [r2arg1, r2arg2];
->r2a : (new <T>(x: T) => string[])[]
->[r2arg1, r2arg2] : (new <T>(x: T) => string[])[]
+>r2a : (new (x: number) => string[])[]
+>[r2arg1, r2arg2] : (new (x: number) => string[])[]
 >r2arg1 : new <T>(x: T) => string[]
 >r2arg2 : new (x: number) => string[]
 
 var r2b = [r2arg2, r2arg1];
->r2b : (new <T>(x: T) => string[])[]
->[r2arg2, r2arg1] : (new <T>(x: T) => string[])[]
+>r2b : (new (x: number) => string[])[]
+>[r2arg2, r2arg1] : (new (x: number) => string[])[]
 >r2arg2 : new (x: number) => string[]
 >r2arg1 : new <T>(x: T) => string[]
 
@@ -383,14 +383,14 @@ var r3 = foo3(r3arg1);
 >r3arg1 : new <T>(x: T) => T
 
 var r3a = [r3arg1, r3arg2];
->r3a : (new <T>(x: T) => T)[]
->[r3arg1, r3arg2] : (new <T>(x: T) => T)[]
+>r3a : (new (x: number) => void)[]
+>[r3arg1, r3arg2] : (new (x: number) => void)[]
 >r3arg1 : new <T>(x: T) => T
 >r3arg2 : new (x: number) => void
 
 var r3b = [r3arg2, r3arg1];
->r3b : (new <T>(x: T) => T)[]
->[r3arg2, r3arg1] : (new <T>(x: T) => T)[]
+>r3b : (new (x: number) => void)[]
+>[r3arg2, r3arg1] : (new (x: number) => void)[]
 >r3arg2 : new (x: number) => void
 >r3arg1 : new <T>(x: T) => T
 
@@ -410,20 +410,20 @@ var r4arg2: new (x: string, y: number) => string;
 >y : number
 
 var r4 = foo4(r4arg1); // any
->r4 : any
->foo4(r4arg1) : any
+>r4 : new (x: string, y: number) => string
+>foo4(r4arg1) : new (x: string, y: number) => string
 >foo4 : { (a: new (x: string, y: number) => string): new (x: string, y: number) => string; (a: any): any; }
 >r4arg1 : new <T, U>(x: T, y: U) => T
 
 var r4a = [r4arg1, r4arg2];
->r4a : (new <T, U>(x: T, y: U) => T)[]
->[r4arg1, r4arg2] : (new <T, U>(x: T, y: U) => T)[]
+>r4a : (new (x: string, y: number) => string)[]
+>[r4arg1, r4arg2] : (new (x: string, y: number) => string)[]
 >r4arg1 : new <T, U>(x: T, y: U) => T
 >r4arg2 : new (x: string, y: number) => string
 
 var r4b = [r4arg2, r4arg1];
->r4b : (new <T, U>(x: T, y: U) => T)[]
->[r4arg2, r4arg1] : (new <T, U>(x: T, y: U) => T)[]
+>r4b : (new (x: string, y: number) => string)[]
+>[r4arg2, r4arg1] : (new (x: string, y: number) => string)[]
 >r4arg2 : new (x: string, y: number) => string
 >r4arg1 : new <T, U>(x: T, y: U) => T
 
@@ -443,20 +443,20 @@ var r5arg2: new (x: new (arg: string) => number) => string;
 >arg : string
 
 var r5 = foo5(r5arg1); // any
->r5 : any
->foo5(r5arg1) : any
+>r5 : new (x: new (arg: string) => number) => string
+>foo5(r5arg1) : new (x: new (arg: string) => number) => string
 >foo5 : { (a: new (x: new (arg: string) => number) => string): new (x: new (arg: string) => number) => string; (a: any): any; }
 >r5arg1 : new <T, U>(x: new (arg: T) => U) => T
 
 var r5a = [r5arg1, r5arg2];
->r5a : (new <T, U>(x: new (arg: T) => U) => T)[]
->[r5arg1, r5arg2] : (new <T, U>(x: new (arg: T) => U) => T)[]
+>r5a : (new (x: new (arg: string) => number) => string)[]
+>[r5arg1, r5arg2] : (new (x: new (arg: string) => number) => string)[]
 >r5arg1 : new <T, U>(x: new (arg: T) => U) => T
 >r5arg2 : new (x: new (arg: string) => number) => string
 
 var r5b = [r5arg2, r5arg1];
->r5b : (new <T, U>(x: new (arg: T) => U) => T)[]
->[r5arg2, r5arg1] : (new <T, U>(x: new (arg: T) => U) => T)[]
+>r5b : (new (x: new (arg: string) => number) => string)[]
+>[r5arg2, r5arg1] : (new (x: new (arg: string) => number) => string)[]
 >r5arg2 : new (x: new (arg: string) => number) => string
 >r5arg1 : new <T, U>(x: new (arg: T) => U) => T
 
@@ -481,20 +481,20 @@ var r6arg2: new (x: new (arg: Base) => Derived) => Base;
 >Base : Base
 
 var r6 = foo6(r6arg1); // any
->r6 : any
->foo6(r6arg1) : any
+>r6 : new (x: new (arg: Base) => Derived) => Base
+>foo6(r6arg1) : new (x: new (arg: Base) => Derived) => Base
 >foo6 : { (a: new (x: new (arg: Base) => Derived) => Base): new (x: new (arg: Base) => Derived) => Base; (a: any): any; }
 >r6arg1 : new <T extends Base, U extends Derived>(x: new (arg: T) => U) => T
 
 var r6a = [r6arg1, r6arg2];
->r6a : (new <T extends Base, U extends Derived>(x: new (arg: T) => U) => T)[]
->[r6arg1, r6arg2] : (new <T extends Base, U extends Derived>(x: new (arg: T) => U) => T)[]
+>r6a : (new (x: new (arg: Base) => Derived) => Base)[]
+>[r6arg1, r6arg2] : (new (x: new (arg: Base) => Derived) => Base)[]
 >r6arg1 : new <T extends Base, U extends Derived>(x: new (arg: T) => U) => T
 >r6arg2 : new (x: new (arg: Base) => Derived) => Base
 
 var r6b = [r6arg2, r6arg1];
->r6b : (new <T extends Base, U extends Derived>(x: new (arg: T) => U) => T)[]
->[r6arg2, r6arg1] : (new <T extends Base, U extends Derived>(x: new (arg: T) => U) => T)[]
+>r6b : (new (x: new (arg: Base) => Derived) => Base)[]
+>[r6arg2, r6arg1] : (new (x: new (arg: Base) => Derived) => Base)[]
 >r6arg2 : new (x: new (arg: Base) => Derived) => Base
 >r6arg1 : new <T extends Base, U extends Derived>(x: new (arg: T) => U) => T
 
@@ -523,20 +523,20 @@ var r7arg2: new (x: new (arg: Base) => Derived) => new (r: Base) => Derived;
 >Derived : Derived
 
 var r7 = foo7(r7arg1); // any
->r7 : any
->foo7(r7arg1) : any
+>r7 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived
+>foo7(r7arg1) : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived
 >foo7 : { (a: new (x: new (arg: Base) => Derived) => new (r: Base) => Derived): new (x: new (arg: Base) => Derived) => new (r: Base) => Derived; (a: any): any; }
 >r7arg1 : new <T extends Base, U extends Derived>(x: new (arg: T) => U) => new (r: T) => U
 
 var r7a = [r7arg1, r7arg2];
->r7a : (new <T extends Base, U extends Derived>(x: new (arg: T) => U) => new (r: T) => U)[]
->[r7arg1, r7arg2] : (new <T extends Base, U extends Derived>(x: new (arg: T) => U) => new (r: T) => U)[]
+>r7a : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived)[]
+>[r7arg1, r7arg2] : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived)[]
 >r7arg1 : new <T extends Base, U extends Derived>(x: new (arg: T) => U) => new (r: T) => U
 >r7arg2 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived
 
 var r7b = [r7arg2, r7arg1];
->r7b : (new <T extends Base, U extends Derived>(x: new (arg: T) => U) => new (r: T) => U)[]
->[r7arg2, r7arg1] : (new <T extends Base, U extends Derived>(x: new (arg: T) => U) => new (r: T) => U)[]
+>r7b : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived)[]
+>[r7arg2, r7arg1] : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived)[]
 >r7arg2 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived
 >r7arg1 : new <T extends Base, U extends Derived>(x: new (arg: T) => U) => new (r: T) => U
 
@@ -573,20 +573,20 @@ var r8arg2: new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived)
 >Derived : Derived
 
 var r8 = foo8(r8arg1); // any
->r8 : any
->foo8(r8arg1) : any
+>r8 : new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived
+>foo8(r8arg1) : new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived
 >foo8 : { (a: new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived): new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived; (a: any): any; }
 >r8arg1 : new <T extends Base, U extends Derived>(x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U
 
 var r8a = [r8arg1, r8arg2];
->r8a : (new <T extends Base, U extends Derived>(x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U)[]
->[r8arg1, r8arg2] : (new <T extends Base, U extends Derived>(x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U)[]
+>r8a : (new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived)[]
+>[r8arg1, r8arg2] : (new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived)[]
 >r8arg1 : new <T extends Base, U extends Derived>(x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U
 >r8arg2 : new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived
 
 var r8b = [r8arg2, r8arg1];
->r8b : (new <T extends Base, U extends Derived>(x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U)[]
->[r8arg2, r8arg1] : (new <T extends Base, U extends Derived>(x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U)[]
+>r8b : (new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived)[]
+>[r8arg2, r8arg1] : (new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived)[]
 >r8arg2 : new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived
 >r8arg1 : new <T extends Base, U extends Derived>(x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U
 
@@ -656,20 +656,20 @@ var r10arg2: new (...x: Derived[]) => Derived;
 >Derived : Derived
 
 var r10 = foo10(r10arg1); // any
->r10 : any
->foo10(r10arg1) : any
+>r10 : new (...x: Derived[]) => Derived
+>foo10(r10arg1) : new (...x: Derived[]) => Derived
 >foo10 : { (a: new (...x: Derived[]) => Derived): new (...x: Derived[]) => Derived; (a: any): any; }
 >r10arg1 : new <T extends Derived>(...x: T[]) => T
 
 var r10a = [r10arg1, r10arg2];
->r10a : (new <T extends Derived>(...x: T[]) => T)[]
->[r10arg1, r10arg2] : (new <T extends Derived>(...x: T[]) => T)[]
+>r10a : (new (...x: Derived[]) => Derived)[]
+>[r10arg1, r10arg2] : (new (...x: Derived[]) => Derived)[]
 >r10arg1 : new <T extends Derived>(...x: T[]) => T
 >r10arg2 : new (...x: Derived[]) => Derived
 
 var r10b = [r10arg2, r10arg1];
->r10b : (new <T extends Derived>(...x: T[]) => T)[]
->[r10arg2, r10arg1] : (new <T extends Derived>(...x: T[]) => T)[]
+>r10b : (new (...x: Derived[]) => Derived)[]
+>[r10arg2, r10arg1] : (new (...x: Derived[]) => Derived)[]
 >r10arg2 : new (...x: Derived[]) => Derived
 >r10arg1 : new <T extends Derived>(...x: T[]) => T
 
@@ -693,20 +693,20 @@ var r11arg2: new (x: { foo: string }, y: { foo: string; bar: string }) => Base;
 >Base : Base
 
 var r11 = foo11(r11arg1); // any
->r11 : any
->foo11(r11arg1) : any
+>r11 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
+>foo11(r11arg1) : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 >foo11 : { (a: new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base): new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base; (a: any): any; }
 >r11arg1 : new <T extends Base>(x: T, y: T) => T
 
 var r11a = [r11arg1, r11arg2];
->r11a : (new <T extends Base>(x: T, y: T) => T)[]
->[r11arg1, r11arg2] : (new <T extends Base>(x: T, y: T) => T)[]
+>r11a : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
+>[r11arg1, r11arg2] : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
 >r11arg1 : new <T extends Base>(x: T, y: T) => T
 >r11arg2 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 
 var r11b = [r11arg2, r11arg1];
->r11b : (new <T extends Base>(x: T, y: T) => T)[]
->[r11arg2, r11arg1] : (new <T extends Base>(x: T, y: T) => T)[]
+>r11b : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
+>[r11arg2, r11arg1] : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
 >r11arg2 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 >r11arg1 : new <T extends Base>(x: T, y: T) => T
 
@@ -741,14 +741,14 @@ var r12 = foo12(r12arg1); // any
 >r12arg1 : new <T extends Base[]>(x: Base[], y: T) => Derived[]
 
 var r12a = [r12arg1, r12arg2];
->r12a : (new <T extends Base[]>(x: Base[], y: T) => Derived[])[]
->[r12arg1, r12arg2] : (new <T extends Base[]>(x: Base[], y: T) => Derived[])[]
+>r12a : (new (x: Base[], y: Derived2[]) => Derived[])[]
+>[r12arg1, r12arg2] : (new (x: Base[], y: Derived2[]) => Derived[])[]
 >r12arg1 : new <T extends Base[]>(x: Base[], y: T) => Derived[]
 >r12arg2 : new (x: Base[], y: Derived2[]) => Derived[]
 
 var r12b = [r12arg2, r12arg1];
->r12b : (new <T extends Base[]>(x: Base[], y: T) => Derived[])[]
->[r12arg2, r12arg1] : (new <T extends Base[]>(x: Base[], y: T) => Derived[])[]
+>r12b : (new (x: Base[], y: Derived2[]) => Derived[])[]
+>[r12arg2, r12arg1] : (new (x: Base[], y: Derived2[]) => Derived[])[]
 >r12arg2 : new (x: Base[], y: Derived2[]) => Derived[]
 >r12arg1 : new <T extends Base[]>(x: Base[], y: T) => Derived[]
 
@@ -776,20 +776,20 @@ var r13arg2: new (x: Array<Base>, y: Array<Derived>) => Array<Derived>;
 >Derived : Derived
 
 var r13 = foo13(r13arg1); // any
->r13 : any
->foo13(r13arg1) : any
+>r13 : new (x: Base[], y: Derived[]) => Derived[]
+>foo13(r13arg1) : new (x: Base[], y: Derived[]) => Derived[]
 >foo13 : { (a: new (x: Base[], y: Derived[]) => Derived[]): new (x: Base[], y: Derived[]) => Derived[]; (a: any): any; }
 >r13arg1 : new <T extends Derived[]>(x: Base[], y: T) => T
 
 var r13a = [r13arg1, r13arg2];
->r13a : (new <T extends Derived[]>(x: Base[], y: T) => T)[]
->[r13arg1, r13arg2] : (new <T extends Derived[]>(x: Base[], y: T) => T)[]
+>r13a : (new (x: Base[], y: Derived[]) => Derived[])[]
+>[r13arg1, r13arg2] : (new (x: Base[], y: Derived[]) => Derived[])[]
 >r13arg1 : new <T extends Derived[]>(x: Base[], y: T) => T
 >r13arg2 : new (x: Base[], y: Derived[]) => Derived[]
 
 var r13b = [r13arg2, r13arg1];
->r13b : (new <T extends Derived[]>(x: Base[], y: T) => T)[]
->[r13arg2, r13arg1] : (new <T extends Derived[]>(x: Base[], y: T) => T)[]
+>r13b : (new (x: Base[], y: Derived[]) => Derived[])[]
+>[r13arg2, r13arg1] : (new (x: Base[], y: Derived[]) => Derived[])[]
 >r13arg2 : new (x: Base[], y: Derived[]) => Derived[]
 >r13arg1 : new <T extends Derived[]>(x: Base[], y: T) => T
 
@@ -811,20 +811,20 @@ var r14arg2: new (x: { a: string; b: number }) => Object;
 >Object : Object
 
 var r14 = foo14(r14arg1); // any
->r14 : any
->foo14(r14arg1) : any
+>r14 : new (x: { a: string; b: number; }) => Object
+>foo14(r14arg1) : new (x: { a: string; b: number; }) => Object
 >foo14 : { (a: new (x: { a: string; b: number; }) => Object): new (x: { a: string; b: number; }) => Object; (a: any): any; }
 >r14arg1 : new <T>(x: { a: T; b: T; }) => T
 
 var r14a = [r14arg1, r14arg2];
->r14a : (new <T>(x: { a: T; b: T; }) => T)[]
->[r14arg1, r14arg2] : (new <T>(x: { a: T; b: T; }) => T)[]
+>r14a : (new (x: { a: string; b: number; }) => Object)[]
+>[r14arg1, r14arg2] : (new (x: { a: string; b: number; }) => Object)[]
 >r14arg1 : new <T>(x: { a: T; b: T; }) => T
 >r14arg2 : new (x: { a: string; b: number; }) => Object
 
 var r14b = [r14arg2, r14arg1];
->r14b : (new <T>(x: { a: T; b: T; }) => T)[]
->[r14arg2, r14arg1] : (new <T>(x: { a: T; b: T; }) => T)[]
+>r14b : (new (x: { a: string; b: number; }) => Object)[]
+>[r14arg2, r14arg1] : (new (x: { a: string; b: number; }) => Object)[]
 >r14arg2 : new (x: { a: string; b: number; }) => Object
 >r14arg1 : new <T>(x: { a: T; b: T; }) => T
 
diff --git a/tests/baselines/reference/subtypingWithConstructSignatures3.types b/tests/baselines/reference/subtypingWithConstructSignatures3.types
index b0f0680c7a088..c5cd256976336 100644
--- a/tests/baselines/reference/subtypingWithConstructSignatures3.types
+++ b/tests/baselines/reference/subtypingWithConstructSignatures3.types
@@ -218,20 +218,20 @@ module Errors {
 >x : number
 
     var r1 = foo2(r1arg1); // any
->r1 : any
->foo2(r1arg1) : any
+>r1 : new (x: number) => string[]
+>foo2(r1arg1) : new (x: number) => string[]
 >foo2 : { (a2: new (x: number) => string[]): new (x: number) => string[]; (a2: any): any; }
 >r1arg1 : new <T, U>(x: T) => U[]
 
     var r1a = [r1arg2, r1arg1];
->r1a : (new <T, U>(x: T) => U[])[]
->[r1arg2, r1arg1] : (new <T, U>(x: T) => U[])[]
+>r1a : (new (x: number) => string[])[]
+>[r1arg2, r1arg1] : (new (x: number) => string[])[]
 >r1arg2 : new (x: number) => string[]
 >r1arg1 : new <T, U>(x: T) => U[]
 
     var r1b = [r1arg1, r1arg2];
->r1b : (new <T, U>(x: T) => U[])[]
->[r1arg1, r1arg2] : (new <T, U>(x: T) => U[])[]
+>r1b : (new (x: number) => string[])[]
+>[r1arg1, r1arg2] : (new (x: number) => string[])[]
 >r1arg1 : new <T, U>(x: T) => U[]
 >r1arg2 : new (x: number) => string[]
 
@@ -262,20 +262,20 @@ module Errors {
 >Derived2 : Derived2
 
     var r2 = foo7(r2arg1); // any
->r2 : any
->foo7(r2arg1) : any
+>r2 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2
+>foo7(r2arg1) : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2
 >foo7 : { (a2: new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2): new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2; (a2: any): any; }
 >r2arg1 : new <T extends Base, U extends Derived, V extends Derived2>(x: new (arg: T) => U) => new (r: T) => V
 
     var r2a = [r2arg2, r2arg1];
->r2a : (new <T extends Base, U extends Derived, V extends Derived2>(x: new (arg: T) => U) => new (r: T) => V)[]
->[r2arg2, r2arg1] : (new <T extends Base, U extends Derived, V extends Derived2>(x: new (arg: T) => U) => new (r: T) => V)[]
+>r2a : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2)[]
+>[r2arg2, r2arg1] : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2)[]
 >r2arg2 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2
 >r2arg1 : new <T extends Base, U extends Derived, V extends Derived2>(x: new (arg: T) => U) => new (r: T) => V
 
     var r2b = [r2arg1, r2arg2];
->r2b : (new <T extends Base, U extends Derived, V extends Derived2>(x: new (arg: T) => U) => new (r: T) => V)[]
->[r2arg1, r2arg2] : (new <T extends Base, U extends Derived, V extends Derived2>(x: new (arg: T) => U) => new (r: T) => V)[]
+>r2b : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2)[]
+>[r2arg1, r2arg2] : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2)[]
 >r2arg1 : new <T extends Base, U extends Derived, V extends Derived2>(x: new (arg: T) => U) => new (r: T) => V
 >r2arg2 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2
 
@@ -344,20 +344,20 @@ module Errors {
 >Base : Base
 
     var r4 = foo10(r4arg1); // any
->r4 : any
->foo10(r4arg1) : any
+>r4 : new (...x: Base[]) => Base
+>foo10(r4arg1) : new (...x: Base[]) => Base
 >foo10 : { (a2: new (...x: Base[]) => Base): new (...x: Base[]) => Base; (a2: any): any; }
 >r4arg1 : new <T extends Derived>(...x: T[]) => T
 
     var r4a = [r4arg2, r4arg1];
->r4a : (new <T extends Derived>(...x: T[]) => T)[]
->[r4arg2, r4arg1] : (new <T extends Derived>(...x: T[]) => T)[]
+>r4a : (new (...x: Base[]) => Base)[]
+>[r4arg2, r4arg1] : (new (...x: Base[]) => Base)[]
 >r4arg2 : new (...x: Base[]) => Base
 >r4arg1 : new <T extends Derived>(...x: T[]) => T
 
     var r4b = [r4arg1, r4arg2];
->r4b : (new <T extends Derived>(...x: T[]) => T)[]
->[r4arg1, r4arg2] : (new <T extends Derived>(...x: T[]) => T)[]
+>r4b : (new (...x: Base[]) => Base)[]
+>[r4arg1, r4arg2] : (new (...x: Base[]) => Base)[]
 >r4arg1 : new <T extends Derived>(...x: T[]) => T
 >r4arg2 : new (...x: Base[]) => Base
 
@@ -381,20 +381,20 @@ module Errors {
 >Base : Base
 
     var r5 = foo11(r5arg1); // any
->r5 : any
->foo11(r5arg1) : any
+>r5 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
+>foo11(r5arg1) : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 >foo11 : { (a2: new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base): new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base; (a2: any): any; }
 >r5arg1 : new <T extends Derived>(x: T, y: T) => T
 
     var r5a = [r5arg2, r5arg1];
->r5a : (new <T extends Derived>(x: T, y: T) => T)[]
->[r5arg2, r5arg1] : (new <T extends Derived>(x: T, y: T) => T)[]
+>r5a : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
+>[r5arg2, r5arg1] : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
 >r5arg2 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 >r5arg1 : new <T extends Derived>(x: T, y: T) => T
 
     var r5b = [r5arg1, r5arg2];
->r5b : (new <T extends Derived>(x: T, y: T) => T)[]
->[r5arg1, r5arg2] : (new <T extends Derived>(x: T, y: T) => T)[]
+>r5b : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
+>[r5arg1, r5arg2] : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[]
 >r5arg1 : new <T extends Derived>(x: T, y: T) => T
 >r5arg2 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base
 
@@ -429,14 +429,14 @@ module Errors {
 >r6arg1 : new (x: Base[], y: Derived2[]) => Derived[]
 
     var r6a = [r6arg2, r6arg1];
->r6a : (new <T extends Derived2[]>(x: Base[], y: Base[]) => T)[]
->[r6arg2, r6arg1] : (new <T extends Derived2[]>(x: Base[], y: Base[]) => T)[]
+>r6a : (new (x: Base[], y: Derived2[]) => Derived[])[]
+>[r6arg2, r6arg1] : (new (x: Base[], y: Derived2[]) => Derived[])[]
 >r6arg2 : new <T extends Derived2[]>(x: Base[], y: Base[]) => T
 >r6arg1 : new (x: Base[], y: Derived2[]) => Derived[]
 
     var r6b = [r6arg1, r6arg2];
->r6b : (new <T extends Derived2[]>(x: Base[], y: Base[]) => T)[]
->[r6arg1, r6arg2] : (new <T extends Derived2[]>(x: Base[], y: Base[]) => T)[]
+>r6b : (new (x: Base[], y: Derived2[]) => Derived[])[]
+>[r6arg1, r6arg2] : (new (x: Base[], y: Derived2[]) => Derived[])[]
 >r6arg1 : new (x: Base[], y: Derived2[]) => Derived[]
 >r6arg2 : new <T extends Derived2[]>(x: Base[], y: Base[]) => T
 
@@ -463,14 +463,14 @@ module Errors {
 >r7arg1 : new <T>(x: { a: T; b: T; }) => T
 
     var r7a = [r7arg2, r7arg1];
->r7a : (new <T>(x: { a: T; b: T; }) => T)[]
->[r7arg2, r7arg1] : (new <T>(x: { a: T; b: T; }) => T)[]
+>r7a : ((new <T>(x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => number))[]
+>[r7arg2, r7arg1] : ((new <T>(x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => number))[]
 >r7arg2 : new (x: { a: string; b: number; }) => number
 >r7arg1 : new <T>(x: { a: T; b: T; }) => T
 
     var r7b = [r7arg1, r7arg2];
->r7b : (new <T>(x: { a: T; b: T; }) => T)[]
->[r7arg1, r7arg2] : (new <T>(x: { a: T; b: T; }) => T)[]
+>r7b : ((new <T>(x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => number))[]
+>[r7arg1, r7arg2] : ((new <T>(x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => number))[]
 >r7arg1 : new <T>(x: { a: T; b: T; }) => T
 >r7arg2 : new (x: { a: string; b: number; }) => number
 
@@ -485,20 +485,20 @@ module Errors {
 >T : T
 
     var r7c = foo15(r7arg3); // any
->r7c : new (x: { a: string; b: number; }) => number
->foo15(r7arg3) : new (x: { a: string; b: number; }) => number
+>r7c : any
+>foo15(r7arg3) : any
 >foo15 : { (a2: new (x: { a: string; b: number; }) => number): new (x: { a: string; b: number; }) => number; (a2: any): any; }
 >r7arg3 : new <T extends Base>(x: { a: T; b: T; }) => number
 
     var r7d = [r7arg2, r7arg3];
->r7d : (new (x: { a: string; b: number; }) => number)[]
->[r7arg2, r7arg3] : (new (x: { a: string; b: number; }) => number)[]
+>r7d : ((new (x: { a: string; b: number; }) => number) | (new <T extends Base>(x: { a: T; b: T; }) => number))[]
+>[r7arg2, r7arg3] : ((new (x: { a: string; b: number; }) => number) | (new <T extends Base>(x: { a: T; b: T; }) => number))[]
 >r7arg2 : new (x: { a: string; b: number; }) => number
 >r7arg3 : new <T extends Base>(x: { a: T; b: T; }) => number
 
     var r7e = [r7arg3, r7arg2];
->r7e : (new (x: { a: string; b: number; }) => number)[]
->[r7arg3, r7arg2] : (new (x: { a: string; b: number; }) => number)[]
+>r7e : ((new (x: { a: string; b: number; }) => number) | (new <T extends Base>(x: { a: T; b: T; }) => number))[]
+>[r7arg3, r7arg2] : ((new (x: { a: string; b: number; }) => number) | (new <T extends Base>(x: { a: T; b: T; }) => number))[]
 >r7arg3 : new <T extends Base>(x: { a: T; b: T; }) => number
 >r7arg2 : new (x: { a: string; b: number; }) => number
 
@@ -555,8 +555,8 @@ module WithGenericSignaturesInBaseType {
 >T : T
 
     var r2 = foo2(r2arg2); // <T>(x:T) => T[] since we can infer from generic signatures now
->r2 : new <T>(x: T) => T[]
->foo2(r2arg2) : new <T>(x: T) => T[]
+>r2 : any
+>foo2(r2arg2) : any
 >foo2 : { (a2: new <T>(x: T) => T[]): new <T>(x: T) => T[]; (a2: any): any; }
 >r2arg2 : new <T>(x: T) => string[]
 
diff --git a/tests/baselines/reference/subtypingWithConstructSignatures4.types b/tests/baselines/reference/subtypingWithConstructSignatures4.types
index 21a40ecf7fcc1..5cf612ed1d070 100644
--- a/tests/baselines/reference/subtypingWithConstructSignatures4.types
+++ b/tests/baselines/reference/subtypingWithConstructSignatures4.types
@@ -301,14 +301,14 @@ var r3 = foo3(r3arg);
 >r3arg : new <T>(x: T) => T
 
 var r3a = [r3arg, r3arg2];
->r3a : (new <T>(x: T) => T)[]
->[r3arg, r3arg2] : (new <T>(x: T) => T)[]
+>r3a : (new <T>(x: T) => void)[]
+>[r3arg, r3arg2] : (new <T>(x: T) => void)[]
 >r3arg : new <T>(x: T) => T
 >r3arg2 : new <T>(x: T) => void
 
 var r3b = [r3arg2, r3arg];
->r3b : (new <T>(x: T) => T)[]
->[r3arg2, r3arg] : (new <T>(x: T) => T)[]
+>r3b : (new <T>(x: T) => void)[]
+>[r3arg2, r3arg] : (new <T>(x: T) => void)[]
 >r3arg2 : new <T>(x: T) => void
 >r3arg : new <T>(x: T) => T
 
@@ -499,14 +499,14 @@ var r15 = foo15(r15arg);
 >r15arg : new <U, V>(x: { a: U; b: V; }) => U[]
 
 var r15a = [r15arg, r15arg2];
->r15a : (new <U, V>(x: { a: U; b: V; }) => U[])[]
->[r15arg, r15arg2] : (new <U, V>(x: { a: U; b: V; }) => U[])[]
+>r15a : (new <T>(x: { a: T; b: T; }) => T[])[]
+>[r15arg, r15arg2] : (new <T>(x: { a: T; b: T; }) => T[])[]
 >r15arg : new <U, V>(x: { a: U; b: V; }) => U[]
 >r15arg2 : new <T>(x: { a: T; b: T; }) => T[]
 
 var r15b = [r15arg2, r15arg];
->r15b : (new <U, V>(x: { a: U; b: V; }) => U[])[]
->[r15arg2, r15arg] : (new <U, V>(x: { a: U; b: V; }) => U[])[]
+>r15b : (new <T>(x: { a: T; b: T; }) => T[])[]
+>[r15arg2, r15arg] : (new <T>(x: { a: T; b: T; }) => T[])[]
 >r15arg2 : new <T>(x: { a: T; b: T; }) => T[]
 >r15arg : new <U, V>(x: { a: U; b: V; }) => U[]
 
diff --git a/tests/baselines/reference/subtypingWithConstructSignatures6.errors.txt b/tests/baselines/reference/subtypingWithConstructSignatures6.errors.txt
new file mode 100644
index 0000000000000..34fa5ee287adc
--- /dev/null
+++ b/tests/baselines/reference/subtypingWithConstructSignatures6.errors.txt
@@ -0,0 +1,142 @@
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(24,11): error TS2430: Interface 'I<T>' incorrectly extends interface 'A'.
+  Types of property 'a' are incompatible.
+    Type 'new (x: T) => T[]' is not assignable to type 'new <T>(x: T) => T[]'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(28,11): error TS2430: Interface 'I2<T>' incorrectly extends interface 'A'.
+  Types of property 'a2' are incompatible.
+    Type 'new (x: T) => string[]' is not assignable to type 'new <T>(x: T) => string[]'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(32,11): error TS2430: Interface 'I3<T>' incorrectly extends interface 'A'.
+  Types of property 'a3' are incompatible.
+    Type 'new (x: T) => T' is not assignable to type 'new <T>(x: T) => void'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(36,11): error TS2430: Interface 'I4<T>' incorrectly extends interface 'A'.
+  Types of property 'a4' are incompatible.
+    Type 'new <U>(x: T, y: U) => string' is not assignable to type 'new <T, U>(x: T, y: U) => string'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(40,11): error TS2430: Interface 'I5<T>' incorrectly extends interface 'A'.
+  Types of property 'a5' are incompatible.
+    Type 'new <U>(x: (arg: T) => U) => T' is not assignable to type 'new <T, U>(x: (arg: T) => U) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Types of parameters 'arg' and 'arg' are incompatible.
+          Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(44,11): error TS2430: Interface 'I7<T>' incorrectly extends interface 'A'.
+  Types of property 'a11' are incompatible.
+    Type 'new <U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type 'new <T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated.
+          Types of property 'foo' are incompatible.
+            Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(48,11): error TS2430: Interface 'I9<T>' incorrectly extends interface 'A'.
+  Types of property 'a16' are incompatible.
+    Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T extends Base>(x: { a: T; b: T; }) => T[]'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated.
+          Types of property 'a' are incompatible.
+            Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+              Type 'Base' is not assignable to type 'T'.
+
+
+==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts (7 errors) ====
+    // checking subtype relations for function types as it relates to contextual signature instantiation
+    // same as subtypingWithConstructSignatures4 but using class type parameters instead of generic signatures
+    // all are errors
+    
+    class Base { foo: string; }
+    class Derived extends Base { bar: string; }
+    class Derived2 extends Derived { baz: string; }
+    class OtherDerived extends Base { bing: string; }
+    
+    interface A { // T
+        // M's
+        a: new <T>(x: T) => T[];
+        a2: new <T>(x: T) => string[];
+        a3: new <T>(x: T) => void;
+        a4: new <T, U>(x: T, y: U) => string;
+        a5: new <T, U>(x: (arg: T) => U) => T;
+        a6: new <T extends Base>(x: (arg: T) => Derived) => T;
+        a11: new <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
+        a15: new <T>(x: { a: T; b: T }) => T[];
+        a16: new <T extends Base>(x: { a: T; b: T }) => T[];
+    }
+    
+    // S's
+    interface I<T> extends A {
+              ~
+!!! error TS2430: Interface 'I<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a' are incompatible.
+!!! error TS2430:     Type 'new (x: T) => T[]' is not assignable to type 'new <T>(x: T) => T[]'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a: new (x: T) => T[]; 
+    }
+    
+    interface I2<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I2<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type 'new (x: T) => string[]' is not assignable to type 'new <T>(x: T) => string[]'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a2: new (x: T) => string[]; 
+    }
+    
+    interface I3<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I3<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a3' are incompatible.
+!!! error TS2430:     Type 'new (x: T) => T' is not assignable to type 'new <T>(x: T) => void'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a3: new (x: T) => T;
+    }
+    
+    interface I4<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I4<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type 'new <U>(x: T, y: U) => string' is not assignable to type 'new <T, U>(x: T, y: U) => string'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a4: new <U>(x: T, y: U) => string; 
+    }
+    
+    interface I5<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I5<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type 'new <U>(x: (arg: T) => U) => T' is not assignable to type 'new <T, U>(x: (arg: T) => U) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Types of parameters 'arg' and 'arg' are incompatible.
+!!! error TS2430:           Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a5: new <U>(x: (arg: T) => U) => T; 
+    }
+    
+    interface I7<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I7<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a11' are incompatible.
+!!! error TS2430:     Type 'new <U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type 'new <T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated.
+!!! error TS2430:           Types of property 'foo' are incompatible.
+!!! error TS2430:             Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+        a11: new <U>(x: { foo: T }, y: { foo: U; bar: U }) => Base; 
+    }
+    
+    interface I9<T> extends A {
+              ~~
+!!! error TS2430: Interface 'I9<T>' incorrectly extends interface 'A'.
+!!! error TS2430:   Types of property 'a16' are incompatible.
+!!! error TS2430:     Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T extends Base>(x: { a: T; b: T; }) => T[]'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated.
+!!! error TS2430:           Types of property 'a' are incompatible.
+!!! error TS2430:             Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+!!! error TS2430:               Type 'Base' is not assignable to type 'T'.
+        a16: new (x: { a: T; b: T }) => T[]; 
+    }
\ No newline at end of file
diff --git a/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt b/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt
index 8a885a2455fb2..a862124666dc4 100644
--- a/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt
+++ b/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt
@@ -2,9 +2,13 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
   Types of property 'a' are incompatible.
     Type 'new (x: string) => string' is not assignable to type '{ new (x: "a"): number; new (x: string): number; }'.
       Type 'string' is not assignable to type 'number'.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignaturesWithSpecializedSignatures.ts(76,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
+  Types of property 'a2' are incompatible.
+    Type 'new <T>(x: T) => string' is not assignable to type 'new <T>(x: T) => T'.
+      Type 'string' is not assignable to type 'T'.
 
 
-==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignaturesWithSpecializedSignatures.ts (1 errors) ====
+==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignaturesWithSpecializedSignatures.ts (2 errors) ====
     // same as subtypingWithCallSignatures but with additional specialized signatures that should not affect the results
     
     module CallSignature {
@@ -86,6 +90,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
     
         // S's
         interface I3 extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type 'new <T>(x: T) => string' is not assignable to type 'new <T>(x: T) => T'.
+!!! error TS2430:       Type 'string' is not assignable to type 'T'.
             // N's
             a2: new <T>(x: T) => string; // error because base returns non-void;
         }
diff --git a/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt b/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt
index e8f50236cba89..1447c4d3105f9 100644
--- a/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt
+++ b/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt
@@ -4,12 +4,86 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(50,15): error TS2430: Interface 'I10<T>' incorrectly extends interface 'Base<T>'.
   Types of property 'a3' are incompatible.
     Type '(x: T, y: T) => T' is not assignable to type '(x: T) => T'.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(100,15): error TS2430: Interface 'I1<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a' are incompatible.
+    Type '() => T' is not assignable to type '<T>() => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(104,15): error TS2430: Interface 'I2<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a' are incompatible.
+    Type '(x?: T) => T' is not assignable to type '<T>() => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(108,15): error TS2430: Interface 'I3<T>' incorrectly extends interface 'Base2'.
   Types of property 'a' are incompatible.
     Type '(x: T) => T' is not assignable to type '<T>() => T'.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(113,15): error TS2430: Interface 'I4<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a2' are incompatible.
+    Type '() => T' is not assignable to type '<T>(x?: T) => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(117,15): error TS2430: Interface 'I5<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a2' are incompatible.
+    Type '(x?: T) => T' is not assignable to type '<T>(x?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(121,15): error TS2430: Interface 'I6<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a2' are incompatible.
+    Type '(x: T) => T' is not assignable to type '<T>(x?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(126,15): error TS2430: Interface 'I7<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a3' are incompatible.
+    Type '() => T' is not assignable to type '<T>(x: T) => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(130,15): error TS2430: Interface 'I8<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a3' are incompatible.
+    Type '(x?: T) => T' is not assignable to type '<T>(x: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(134,15): error TS2430: Interface 'I9<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a3' are incompatible.
+    Type '(x: T) => T' is not assignable to type '<T>(x: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(138,15): error TS2430: Interface 'I10<T>' incorrectly extends interface 'Base2'.
   Types of property 'a3' are incompatible.
     Type '(x: T, y: T) => T' is not assignable to type '<T>(x: T) => T'.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(143,15): error TS2430: Interface 'I11<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a4' are incompatible.
+    Type '() => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(147,15): error TS2430: Interface 'I12<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a4' are incompatible.
+    Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(151,15): error TS2430: Interface 'I13<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a4' are incompatible.
+    Type '(x: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(155,15): error TS2430: Interface 'I14<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a4' are incompatible.
+    Type '(x: T, y: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(160,15): error TS2430: Interface 'I15<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a5' are incompatible.
+    Type '() => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(164,15): error TS2430: Interface 'I16<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a5' are incompatible.
+    Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(168,15): error TS2430: Interface 'I17<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a5' are incompatible.
+    Type '(x: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(172,15): error TS2430: Interface 'I18<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a5' are incompatible.
+    Type '(x: T, y: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(196,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
   Types of property 'a' are incompatible.
     Type '<T>(x: T) => T' is not assignable to type '<T>() => T'.
@@ -18,7 +92,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
     Type '<T>(x: T, y: T) => T' is not assignable to type '<T>(x: T) => T'.
 
 
-==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts (6 errors) ====
+==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts (22 errors) ====
     // call signatures in derived types must have the same or fewer optional parameters as the base type
     
     module ClassTypeParam {
@@ -127,10 +201,20 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
         }
     
         interface I1<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I1<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a' are incompatible.
+!!! error TS2430:     Type '() => T' is not assignable to type '<T>() => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a: () => T; 
         }
     
         interface I2<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I2<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a' are incompatible.
+!!! error TS2430:     Type '(x?: T) => T' is not assignable to type '<T>() => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a: (x?: T) => T;
         }
     
@@ -144,27 +228,61 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
     
     
         interface I4<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I4<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type '() => T' is not assignable to type '<T>(x?: T) => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a2: () => T; 
         }
     
         interface I5<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I5<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type '(x?: T) => T' is not assignable to type '<T>(x?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a2: (x?: T) => T
         }
     
         interface I6<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I6<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type '(x: T) => T' is not assignable to type '<T>(x?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a2: (x: T) => T;
         }
     
     
         interface I7<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I7<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a3' are incompatible.
+!!! error TS2430:     Type '() => T' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a3: () => T;
         }
     
         interface I8<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I8<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a3' are incompatible.
+!!! error TS2430:     Type '(x?: T) => T' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a3: (x?: T) => T; 
         }
     
         interface I9<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I9<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a3' are incompatible.
+!!! error TS2430:     Type '(x: T) => T' is not assignable to type '<T>(x: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a3: (x: T) => T; 
         }
     
@@ -178,35 +296,81 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
     
     
         interface I11<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I11<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type '() => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a4: () => T; 
         }
     
         interface I12<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I12<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a4: (x?: T, y?: T) => T; 
         }
     
         interface I13<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I13<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type '(x: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a4: (x: T) => T; 
         }
     
         interface I14<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I14<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type '(x: T, y: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a4: (x: T, y: T) => T; 
         }
     
     
         interface I15<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I15<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type '() => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a5: () => T; 
         }
     
         interface I16<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I16<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a5: (x?: T, y?: T) => T; 
         }
     
         interface I17<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I17<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type '(x: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a5: (x: T) => T;
         }
     
         interface I18<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I18<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type '(x: T, y: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a5: (x: T, y: T) => T; 
         }
     }
diff --git a/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt b/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt
index 27066058238c9..28682b99a6604 100644
--- a/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt
+++ b/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt
@@ -4,12 +4,86 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(50,15): error TS2430: Interface 'I10<T>' incorrectly extends interface 'Base<T>'.
   Types of property 'a3' are incompatible.
     Type 'new (x: T, y: T) => T' is not assignable to type 'new (x: T) => T'.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(100,15): error TS2430: Interface 'I1<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a' are incompatible.
+    Type 'new () => T' is not assignable to type 'new <T>() => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(104,15): error TS2430: Interface 'I2<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a' are incompatible.
+    Type 'new (x?: T) => T' is not assignable to type 'new <T>() => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(108,15): error TS2430: Interface 'I3<T>' incorrectly extends interface 'Base2'.
   Types of property 'a' are incompatible.
     Type 'new (x: T) => T' is not assignable to type 'new <T>() => T'.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(113,15): error TS2430: Interface 'I4<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a2' are incompatible.
+    Type 'new () => T' is not assignable to type 'new <T>(x?: T) => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(117,15): error TS2430: Interface 'I5<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a2' are incompatible.
+    Type 'new (x?: T) => T' is not assignable to type 'new <T>(x?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(121,15): error TS2430: Interface 'I6<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a2' are incompatible.
+    Type 'new (x: T) => T' is not assignable to type 'new <T>(x?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(126,15): error TS2430: Interface 'I7<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a3' are incompatible.
+    Type 'new () => T' is not assignable to type 'new <T>(x: T) => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(130,15): error TS2430: Interface 'I8<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a3' are incompatible.
+    Type 'new (x?: T) => T' is not assignable to type 'new <T>(x: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(134,15): error TS2430: Interface 'I9<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a3' are incompatible.
+    Type 'new (x: T) => T' is not assignable to type 'new <T>(x: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(138,15): error TS2430: Interface 'I10<T>' incorrectly extends interface 'Base2'.
   Types of property 'a3' are incompatible.
     Type 'new (x: T, y: T) => T' is not assignable to type 'new <T>(x: T) => T'.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(143,15): error TS2430: Interface 'I11<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a4' are incompatible.
+    Type 'new () => T' is not assignable to type 'new <T>(x: T, y?: T) => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(147,15): error TS2430: Interface 'I12<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a4' are incompatible.
+    Type 'new (x?: T, y?: T) => T' is not assignable to type 'new <T>(x: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(151,15): error TS2430: Interface 'I13<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a4' are incompatible.
+    Type 'new (x: T) => T' is not assignable to type 'new <T>(x: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(155,15): error TS2430: Interface 'I14<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a4' are incompatible.
+    Type 'new (x: T, y: T) => T' is not assignable to type 'new <T>(x: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(160,15): error TS2430: Interface 'I15<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a5' are incompatible.
+    Type 'new () => T' is not assignable to type 'new <T>(x?: T, y?: T) => T'.
+      Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(164,15): error TS2430: Interface 'I16<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a5' are incompatible.
+    Type 'new (x?: T, y?: T) => T' is not assignable to type 'new <T>(x?: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(168,15): error TS2430: Interface 'I17<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a5' are incompatible.
+    Type 'new (x: T) => T' is not assignable to type 'new <T>(x?: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
+tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(172,15): error TS2430: Interface 'I18<T>' incorrectly extends interface 'Base2'.
+  Types of property 'a5' are incompatible.
+    Type 'new (x: T, y: T) => T' is not assignable to type 'new <T>(x?: T, y?: T) => T'.
+      Types of parameters 'x' and 'x' are incompatible.
+        Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(196,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
   Types of property 'a' are incompatible.
     Type 'new <T>(x: T) => T' is not assignable to type 'new <T>() => T'.
@@ -18,7 +92,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
     Type 'new <T>(x: T, y: T) => T' is not assignable to type 'new <T>(x: T) => T'.
 
 
-==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts (6 errors) ====
+==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts (22 errors) ====
     // call signatures in derived types must have the same or fewer optional parameters as the base type
     
     module ClassTypeParam {
@@ -127,10 +201,20 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
         }
     
         interface I1<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I1<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a' are incompatible.
+!!! error TS2430:     Type 'new () => T' is not assignable to type 'new <T>() => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a: new () => T; 
         }
     
         interface I2<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I2<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a' are incompatible.
+!!! error TS2430:     Type 'new (x?: T) => T' is not assignable to type 'new <T>() => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a: new (x?: T) => T;
         }
     
@@ -144,27 +228,61 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
     
     
         interface I4<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I4<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type 'new () => T' is not assignable to type 'new <T>(x?: T) => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a2: new () => T; 
         }
     
         interface I5<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I5<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type 'new (x?: T) => T' is not assignable to type 'new <T>(x?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a2: new (x?: T) => T
         }
     
         interface I6<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I6<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a2' are incompatible.
+!!! error TS2430:     Type 'new (x: T) => T' is not assignable to type 'new <T>(x?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a2: new (x: T) => T;
         }
     
     
         interface I7<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I7<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a3' are incompatible.
+!!! error TS2430:     Type 'new () => T' is not assignable to type 'new <T>(x: T) => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a3: new () => T;
         }
     
         interface I8<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I8<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a3' are incompatible.
+!!! error TS2430:     Type 'new (x?: T) => T' is not assignable to type 'new <T>(x: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a3: new (x?: T) => T; 
         }
     
         interface I9<T> extends Base2 {
+                  ~~
+!!! error TS2430: Interface 'I9<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a3' are incompatible.
+!!! error TS2430:     Type 'new (x: T) => T' is not assignable to type 'new <T>(x: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a3: new (x: T) => T; 
         }
     
@@ -178,35 +296,81 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW
     
     
         interface I11<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I11<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type 'new () => T' is not assignable to type 'new <T>(x: T, y?: T) => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a4: new () => T; 
         }
     
         interface I12<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I12<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type 'new (x?: T, y?: T) => T' is not assignable to type 'new <T>(x: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a4: new (x?: T, y?: T) => T; 
         }
     
         interface I13<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I13<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type 'new (x: T) => T' is not assignable to type 'new <T>(x: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a4: new (x: T) => T; 
         }
     
         interface I14<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I14<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a4' are incompatible.
+!!! error TS2430:     Type 'new (x: T, y: T) => T' is not assignable to type 'new <T>(x: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a4: new (x: T, y: T) => T; 
         }
     
     
         interface I15<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I15<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type 'new () => T' is not assignable to type 'new <T>(x?: T, y?: T) => T'.
+!!! error TS2430:       Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a5: new () => T; 
         }
     
         interface I16<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I16<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type 'new (x?: T, y?: T) => T' is not assignable to type 'new <T>(x?: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a5: new (x?: T, y?: T) => T; 
         }
     
         interface I17<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I17<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type 'new (x: T) => T' is not assignable to type 'new <T>(x?: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a5: new (x: T) => T;
         }
     
         interface I18<T> extends Base2 {
+                  ~~~
+!!! error TS2430: Interface 'I18<T>' incorrectly extends interface 'Base2'.
+!!! error TS2430:   Types of property 'a5' are incompatible.
+!!! error TS2430:     Type 'new (x: T, y: T) => T' is not assignable to type 'new <T>(x?: T, y?: T) => T'.
+!!! error TS2430:       Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2430:         Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
             a5: new (x: T, y: T) => T; 
         }
     }
diff --git a/tests/baselines/reference/typeParameterConstrainedToOuterTypeParameter.errors.txt b/tests/baselines/reference/typeParameterConstrainedToOuterTypeParameter.errors.txt
new file mode 100644
index 0000000000000..926ad4b3bffe0
--- /dev/null
+++ b/tests/baselines/reference/typeParameterConstrainedToOuterTypeParameter.errors.txt
@@ -0,0 +1,22 @@
+tests/cases/compiler/typeParameterConstrainedToOuterTypeParameter.ts(10,5): error TS2322: Type 'A<string>' is not assignable to type 'B<string>'.
+  Types of parameters 'x' and 'x' are incompatible.
+    Type 'U' is not assignable to type 'string[]'.
+      Type 'string' is not assignable to type 'string[]'.
+
+
+==== tests/cases/compiler/typeParameterConstrainedToOuterTypeParameter.ts (1 errors) ====
+    interface A<T> {
+        <U extends T>(x: U[])
+    }
+    
+    interface B<T> {
+        <U extends T>(x: U)
+    }
+    
+    var a: A<string>
+    var b: B<string> = a; // assignment should be legal (both U's get instantiated to any for comparison)
+        ~
+!!! error TS2322: Type 'A<string>' is not assignable to type 'B<string>'.
+!!! error TS2322:   Types of parameters 'x' and 'x' are incompatible.
+!!! error TS2322:     Type 'U' is not assignable to type 'string[]'.
+!!! error TS2322:       Type 'string' is not assignable to type 'string[]'.
\ No newline at end of file
diff --git a/tests/baselines/reference/underscoreTest1.errors.txt b/tests/baselines/reference/underscoreTest1.errors.txt
new file mode 100644
index 0000000000000..ca8df7922314e
--- /dev/null
+++ b/tests/baselines/reference/underscoreTest1.errors.txt
@@ -0,0 +1,908 @@
+tests/cases/compiler/underscoreTest1_underscoreTests.ts(26,7): error TS2345: Argument of type '(string | number | boolean)[]' is not assignable to parameter of type 'Dictionary<{}>'.
+  Index signature is missing in type '(string | number | boolean)[]'.
+
+
+==== tests/cases/compiler/underscoreTest1_underscoreTests.ts (1 errors) ====
+    /// <reference path="underscoreTest1_underscore.ts" />
+    
+    declare var $;
+    declare function alert(x: string): void;
+    
+    _.each([1, 2, 3], (num) => alert(num.toString()));
+    _.each({ one: 1, two: 2, three: 3 }, (value: number, key?: string) => alert(value.toString()));
+    
+    _.map([1, 2, 3], (num) => num * 3);
+    _.map({ one: 1, two: 2, three: 3 }, (value: number, key?: string) => value * 3);
+    
+    var sum = _.reduce([1, 2, 3], (memo, num) => memo + num, 0);
+    
+    var list = [[0, 1], [2, 3], [4, 5]];
+    var flat = _.reduceRight(list, (a, b) => a.concat(b), []);
+    
+    var even = _.find([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0);
+    
+    var evens = _.filter([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0);
+    
+    var listOfPlays = [{ title: "Cymbeline", author: "Shakespeare", year: 1611 }, { title: "The Tempest", author: "Shakespeare", year: 1611 }, { title: "Other", author: "Not Shakespeare", year: 2012 }];
+    _.where(listOfPlays, { author: "Shakespeare", year: 1611 });
+    
+    var odds = _.reject([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0);
+    
+    _.all([true, 1, null, 'yes'], _.identity);
+          ~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2345: Argument of type '(string | number | boolean)[]' is not assignable to parameter of type 'Dictionary<{}>'.
+!!! error TS2345:   Index signature is missing in type '(string | number | boolean)[]'.
+    
+    _.any([null, 0, 'yes', false]);
+    
+    _.contains([1, 2, 3], 3);
+    
+    _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
+    
+    var stooges = [{ name: 'moe', age: 40 }, { name: 'larry', age: 50 }, { name: 'curly', age: 60 }];
+    _.pluck(stooges, 'name');
+    
+    _.max(stooges, (stooge) => stooge.age);
+    
+    var numbers = [10, 5, 100, 2, 1000];
+    _.min(numbers);
+    
+    _.sortBy([1, 2, 3, 4, 5, 6], (num) => Math.sin(num));
+    
+    
+    // not sure how this is typechecking at all.. Math.floor(e) is number not string..?
+    _([1.3, 2.1, 2.4]).groupBy((e: number, i?: number, list?: number[]) => Math.floor(e));
+    _.groupBy([1.3, 2.1, 2.4], (num: number) => Math.floor(num));
+    _.groupBy(['one', 'two', 'three'], 'length');
+    
+    _.countBy([1, 2, 3, 4, 5], (num) => num % 2 == 0 ? 'even' : 'odd');
+    
+    _.shuffle([1, 2, 3, 4, 5, 6]);
+    
+    // (function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
+    
+    _.size({ one: 1, two: 2, three: 3 });
+    
+    ///////////////////////////////////////////////////////////////////////////////////////
+    
+    _.first([5, 4, 3, 2, 1]);
+    _.initial([5, 4, 3, 2, 1]);
+    _.last([5, 4, 3, 2, 1]);
+    _.rest([5, 4, 3, 2, 1]);
+    _.compact([0, 1, false, 2, '', 3]);
+    
+    _.flatten([1, 2, 3, 4]);
+    _.flatten([1, [2]]);
+    
+    // typescript doesn't like the elements being different
+    _.flatten([1, [2], [3, [[4]]]]);
+    _.flatten([1, [2], [3, [[4]]]], true);
+    _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
+    _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
+    _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
+    _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
+    _.uniq([1, 2, 1, 3, 1, 4]);
+    _.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
+    _.object(['moe', 'larry', 'curly'], [30, 40, 50]);
+    _.object([['moe', 30], ['larry', 40], ['curly', 50]]);
+    _.indexOf([1, 2, 3], 2);
+    _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
+    _.sortedIndex([10, 20, 30, 40, 50], 35);
+    _.range(10);
+    _.range(1, 11);
+    _.range(0, 30, 5);
+    _.range(0, 30, 5);
+    _.range(0);
+    
+    ///////////////////////////////////////////////////////////////////////////////////////
+    
+    var func = function (greeting) { return greeting + ': ' + this.name };
+    // need a second var otherwise typescript thinks func signature is the above func type,
+    // instead of the newly returned _bind => func type.
+    var func2 = _.bind(func, { name: 'moe' }, 'hi');
+    func2();
+    
+    var buttonView = {
+        label: 'underscore',
+        onClick: function () { alert('clicked: ' + this.label); },
+        onHover: function () { alert('hovering: ' + this.label); }
+    };
+    _.bindAll(buttonView);
+    $('#underscore_button').bind('click', buttonView.onClick);
+    
+    var fibonacci = _.memoize(function (n) {
+        return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
+    });
+    
+    var log = _.bind((message?: string, ...rest: string[]) => { }, Date);
+    _.delay(log, 1000, 'logged later');
+    
+    _.defer(function () { alert('deferred'); });
+    
+    var updatePosition = () => alert('updating position...');
+    var throttled = _.throttle(updatePosition, 100);
+    $(null).scroll(throttled);
+    
+    var calculateLayout = () => alert('calculating layout...');
+    var lazyLayout = _.debounce(calculateLayout, 300);
+    $(null).resize(lazyLayout);
+    
+    var createApplication = () => alert('creating application...');
+    var initialize = _.once(createApplication);
+    initialize();
+    initialize();
+    
+    var notes: any[];
+    var render = () => alert("rendering...");
+    var renderNotes = _.after(notes.length, render);
+    _.each(notes, (note) => note.asyncSave({ success: renderNotes }));
+    
+    var hello = function (name) { return "hello: " + name; };
+    hello = _.wrap(hello, (func, arg) => { return "before, " + func(arg) + ", after"; });
+    hello("moe");
+    
+    var greet = function (name) { return "hi: " + name; };
+    var exclaim = function (statement) { return statement + "!"; };
+    var welcome = _.compose(exclaim, greet);
+    welcome('moe');
+    
+    ///////////////////////////////////////////////////////////////////////////////////////
+    
+    _.keys({ one: 1, two: 2, three: 3 });
+    _.values({ one: 1, two: 2, three: 3 });
+    _.pairs({ one: 1, two: 2, three: 3 });
+    _.invert({ Moe: "Moses", Larry: "Louis", Curly: "Jerome" });
+    _.functions(_);
+    _.extend({ name: 'moe' }, { age: 50 });
+    _.pick({ name: 'moe', age: 50, userid: 'moe1' }, 'name', 'age');
+    _.omit({ name: 'moe', age: 50, userid: 'moe1' }, 'userid');
+    
+    var iceCream = { flavor: "chocolate" };
+    _.defaults(iceCream, { flavor: "vanilla", sprinkles: "lots" });
+    
+    _.clone({ name: 'moe' });
+    
+    _.chain([1, 2, 3, 200])
+        .filter(function (num) { return num % 2 == 0; })
+        .tap(<any>alert)
+        .map(function (num) { return num * num })
+        .value();
+    
+    _.has({ a: 1, b: 2, c: 3 }, "b");
+    
+    var moe = { name: 'moe', luckyNumbers: [13, 27, 34] };
+    var clone = { name: 'moe', luckyNumbers: [13, 27, 34] };
+    moe == clone;
+    _.isEqual(moe, clone);
+    
+    _.isEmpty([1, 2, 3]);
+    _.isEmpty({});
+    
+    _.isElement($('body')[0]);
+    
+    (function () { return _.isArray(arguments); })();
+    _.isArray([1, 2, 3]);
+    
+    _.isObject({});
+    _.isObject(1);
+    
+    
+    // (() => { return _.isArguments(arguments); })(1, 2, 3);
+    _.isArguments([1, 2, 3]);
+    
+    _.isFunction(alert);
+    
+    _.isString("moe");
+    
+    _.isNumber(8.4 * 5);
+    
+    _.isFinite(-101);
+    
+    _.isFinite(-Infinity);
+    
+    _.isBoolean(null);
+    
+    _.isDate(new Date());
+    
+    _.isRegExp(/moe/);
+    
+    _.isNaN(NaN);
+    isNaN(undefined);
+    _.isNaN(undefined);
+    
+    _.isNull(null);
+    _.isNull(undefined);
+    
+    _.isUndefined((<any>null).missingVariable);
+    
+    ///////////////////////////////////////////////////////////////////////////////////////
+    
+    var underscore = _.noConflict();
+    
+    var moe2 = { name: 'moe' };
+    moe2 === _.identity(moe);
+    
+    var genie;
+    
+    _.times(3, function (n) { genie.grantWishNumber(n); });
+    
+    _.random(0, 100);
+    
+    _.mixin({
+        capitalize: function (string) {
+            return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
+        }
+    });
+    (<any>_("fabio")).capitalize();
+    
+    _.uniqueId('contact_');
+    
+    _.escape('Curly, Larry & Moe');
+    
+    var object = { cheese: 'crumpets', stuff: function () { return 'nonsense'; } };
+    _.result(object, 'cheese');
+    
+    _.result(object, 'stuff');
+    
+    var compiled = _.template("hello: <%= name %>");
+    compiled({ name: 'moe' });
+    var list2 = "<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>";
+    _.template(list2, { people: ['moe', 'curly', 'larry'] });
+    var template = _.template("<b><%- value %></b>");
+    template({ value: '<script>' });
+    var compiled2 = _.template("<% print('Hello ' + epithet); %>");
+    compiled2({ epithet: "stooge" });
+    _.templateSettings = {
+        interpolate: /\{\{(.+?)\}\}/g
+    };
+    var template2 = _.template("Hello {{ name }}!");
+    template2({ name: "Mustache" });
+    _.template("Using 'with': <%= data.answer %>", { answer: 'no' }, { variable: 'data' });
+==== tests/cases/compiler/underscoreTest1_underscore.ts (0 errors) ====
+    interface Dictionary<T> {
+        [x: string]: T;
+    }
+    
+    interface Iterator_<T, U> {
+        (value: T, index: any, list: any): U;
+    }
+    
+    interface Reducer<T, U> {
+        (accumulator: U, value: T, index: any, list: any): U;
+    }
+    
+    interface Tuple2<T0, T1> extends Array<any> {
+        0: T0;
+        1: T1;
+    }
+    
+    interface Tuple3<T0, T1, T2> extends Array<any> {
+        0: T0;
+        1: T1;
+        2: T2;
+    }
+    
+    interface Tuple4<T0, T1, T2, T3> extends Array<any> {
+        0: T0;
+        1: T1;
+        2: T2;
+        3: T3;
+    }
+    
+    module Underscore {
+        export interface WrappedObject<T> {
+            keys(): string[];
+            values(): any[];
+            pairs(): any[][];
+            invert(): any;
+            functions(): string[];
+            methods(): string[];
+            extend(...sources: any[]): T;
+            pick(...keys: string[]): T;
+            omit(...keys: string[]): T;
+            defaults(...defaults: any[]): T;
+            clone(): T;
+            tap(interceptor: (object: T) => void): T;
+            has(key: string): boolean;
+            isEqual(other: T): boolean;
+            isEmpty(): boolean;
+            isElement(): boolean;
+            isArray(): boolean;
+            isObject(): boolean;
+            isArguments(): boolean;
+            isFunction(): boolean;
+            isString(): boolean;
+            isNumber(): boolean;
+            isFinite(): boolean;
+            isBoolean(): boolean;
+            isDate(): boolean;
+            isRegExp(): boolean;
+            isNaN(): boolean;
+            isNull(): boolean;
+            isUndefined(): boolean;
+            value(): T;
+        }
+    
+        export interface WrappedFunction<T extends Function> extends WrappedObject<T> {
+            bind(object: any): T;
+            bind(object: any, ...args: any[]): Function;
+            bindAll(...methodNames: string[]): T;
+            partial(...args: any[]): Function;
+            memoize(hashFunction?: Function): T;
+            delay(wait: number, ...args: any[]): number;
+            defer(...args: any[]): number;
+            throttle(wait: number): T;
+            debounce(wait: number, immediate?: boolean): T;
+            once(): T;
+            wrap(wrapper: (func: T, ...args: any[]) => any): T;
+            compose(...funcs: Function[]): Function;
+        }
+    
+        export interface WrappedArray<T> extends WrappedObject<Array<T>> {
+            each(iterator: Iterator_<T, void>, context?: any): void;
+            forEach(iterator: Iterator_<T, void>, context?: any): void;
+            map<U>(iterator: Iterator_<T, U>, context?: any): U[];
+            collect<U>(iterator: Iterator_<T, U>, context?: any): U[];
+            reduce(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            reduce<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            foldl(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            foldl<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            inject(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            inject<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            reduceRight(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            reduceRight<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            foldr(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            foldr<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            find(iterator: Iterator_<T, boolean>, context?: any): T;
+            detect(iterator: Iterator_<T, boolean>, context?: any): T;
+            filter(iterator: Iterator_<T, boolean>, context?: any): T[];
+            select(iterator: Iterator_<T, boolean>, context?: any): T[];
+            where(properties: Object): T[];
+            findWhere(properties: Object): T;
+            reject(iterator: Iterator_<T, boolean>, context?: any): T[];
+            every(iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            all(iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            some(iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            any(iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            contains(value: T): boolean;
+            include(value: T): boolean;
+            invoke(methodName: string, ...args: any[]): any[];
+            pluck(propertyName: string): any[];
+            max(iterator?: Iterator_<T, any>, context?: any): T;
+            min(iterator?: Iterator_<T, any>, context?: any): T;
+            sortBy(iterator: Iterator_<T, any>, context?: any): T[];
+            sortBy(propertyName: string): T[];
+            groupBy(iterator?: Iterator_<T, any>, context?: any): Dictionary<T[]>;
+            groupBy(propertyName: string): Dictionary<T[]>;
+            countBy(iterator?: Iterator_<T, any>, context?: any): Dictionary<number>;
+            countBy(propertyName: string): Dictionary<number>;
+            shuffle(): T[];
+            toArray(): T[];
+            size(): number;
+            first(): T;
+            first(count: number): T[];
+            head(): T;
+            head(count: number): T[];
+            take(): T;
+            take(count: number): T[];
+            initial(): T;
+            initial(count: number): T[];
+            last(): T;
+            last(count: number): T[];
+            rest(index?: number): T[];
+            compact(): T[];
+            flatten<U>(shallow?: boolean): U[];
+            without(...values: T[]): T[];
+            union(...arrays: T[][]): T[];
+            intersection(...arrays: T[][]): T[];
+            difference(...others: T[][]): T[];
+            uniq(isSorted?: boolean): T[];
+            uniq<U>(isSorted: boolean, iterator: Iterator_<T, U>, context?: any): U[];
+            unique(isSorted?: boolean): T[];
+            unique<U>(isSorted: boolean, iterator: Iterator_<T, U>, context?: any): U[];
+            zip(...arrays: any[][]): any[][];
+            object(): any;
+            object(values: any[]): any;
+            indexOf(value: T, isSorted?: boolean): number;
+            lastIndexOf(value: T, fromIndex?: number): number;
+            sortedIndex(obj: T, propertyName: string): number;
+            sortedIndex(obj: T, iterator?: Iterator_<T, any>, context?: any): number;
+            // Methods from Array
+            concat(...items: T[]): T[];
+            join(separator?: string): string;
+            pop(): T;
+            push(...items: T[]): number;
+            reverse(): T[];
+            shift(): T;
+            slice(start: number, end?: number): T[];
+            sort(compareFn?: (a: T, b: T) => number): T[];
+            splice(start: number): T[];
+            splice(start: number, deleteCount: number, ...items: T[]): T[];
+            unshift(...items: T[]): number;
+        }
+    
+        export interface WrappedDictionary<T> extends WrappedObject<Dictionary<T>> {
+            each(iterator: Iterator_<T, void>, context?: any): void;
+            forEach(iterator: Iterator_<T, void>, context?: any): void;
+            map<U>(iterator: Iterator_<T, U>, context?: any): U[];
+            collect<U>(iterator: Iterator_<T, U>, context?: any): U[];
+            reduce(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            reduce<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            foldl(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            foldl<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            inject(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            inject<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            reduceRight(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            reduceRight<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            foldr(iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            foldr<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            find(iterator: Iterator_<T, boolean>, context?: any): T;
+            detect(iterator: Iterator_<T, boolean>, context?: any): T;
+            filter(iterator: Iterator_<T, boolean>, context?: any): T[];
+            select(iterator: Iterator_<T, boolean>, context?: any): T[];
+            where(properties: Object): T[];
+            findWhere(properties: Object): T;
+            reject(iterator: Iterator_<T, boolean>, context?: any): T[];
+            every(iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            all(iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            some(iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            any(iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            contains(value: T): boolean;
+            include(value: T): boolean;
+            invoke(methodName: string, ...args: any[]): any[];
+            pluck(propertyName: string): any[];
+            max(iterator?: Iterator_<T, any>, context?: any): T;
+            min(iterator?: Iterator_<T, any>, context?: any): T;
+            sortBy(iterator: Iterator_<T, any>, context?: any): T[];
+            sortBy(propertyName: string): T[];
+            groupBy(iterator?: Iterator_<T, any>, context?: any): Dictionary<T[]>;
+            groupBy(propertyName: string): Dictionary<T[]>;
+            countBy(iterator?: Iterator_<T, any>, context?: any): Dictionary<number>;
+            countBy(propertyName: string): Dictionary<number>;
+            shuffle(): T[];
+            toArray(): T[];
+            size(): number;
+        }
+    
+        export interface ChainedObject<T> {
+            keys(): ChainedArray<string>;
+            values(): ChainedArray<any>;
+            pairs(): ChainedArray<any[]>;
+            invert(): ChainedObject<any>;
+            functions(): ChainedArray<string>;
+            methods(): ChainedArray<string>;
+            extend(...sources: any[]): ChainedObject<T>;
+            pick(...keys: string[]): ChainedObject<T>;
+            omit(...keys: string[]): ChainedObject<T>;
+            defaults(...defaults: any[]): ChainedObject<T>;
+            clone(): ChainedObject<T>;
+            tap(interceptor: (object: T) => void): ChainedObject<T>;
+            has(key: string): ChainedObject<boolean>;
+            isEqual(other: T): ChainedObject<boolean>;
+            isEmpty(): ChainedObject<boolean>;
+            isElement(): ChainedObject<boolean>;
+            isArray(): ChainedObject<boolean>;
+            isObject(): ChainedObject<boolean>;
+            isArguments(): ChainedObject<boolean>;
+            isFunction(): ChainedObject<boolean>;
+            isString(): ChainedObject<boolean>;
+            isNumber(): ChainedObject<boolean>;
+            isFinite(): ChainedObject<boolean>;
+            isBoolean(): ChainedObject<boolean>;
+            isDate(): ChainedObject<boolean>;
+            isRegExp(): ChainedObject<boolean>;
+            isNaN(): ChainedObject<boolean>;
+            isNull(): ChainedObject<boolean>;
+            isUndefined(): ChainedObject<boolean>;
+            value(): T;
+        }
+    
+        export interface ChainedArray<T> extends ChainedObject<Array<T>> {
+            each(iterator: Iterator_<T, void>, context?: any): ChainedObject<void>;
+            forEach(iterator: Iterator_<T, void>, context?: any): ChainedObject<void>;
+            map<U>(iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
+            collect<U>(iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
+            reduce(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
+            reduce<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
+            foldl(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
+            foldl<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
+            inject(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
+            inject<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
+            reduceRight(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
+            reduceRight<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
+            foldr(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
+            foldr<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
+            find(iterator: Iterator_<T, boolean>, context?: any): ChainedObject<T>;
+            detect(iterator: Iterator_<T, boolean>, context?: any): ChainedObject<T>;
+            filter(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
+            select(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
+            where(properties: Object): ChainedArray<T>;
+            findWhere(properties: Object): ChainedObject<T>;
+            reject(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
+            every(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
+            all(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
+            some(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
+            any(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
+            contains(value: T): ChainedObject<boolean>;
+            include(value: T): ChainedObject<boolean>;
+            invoke(methodName: string, ...args: any[]): ChainedArray<any>;
+            pluck(propertyName: string): ChainedArray<any>;
+            max(iterator?: Iterator_<T, any>, context?: any): ChainedObject<T>;
+            min(iterator?: Iterator_<T, any>, context?: any): ChainedObject<T>;
+            sortBy(iterator: Iterator_<T, any>, context?: any): ChainedArray<T>;
+            sortBy(propertyName: string): ChainedArray<T>;
+            // Should return ChainedDictionary<T[]>, but expansive recursion not allowed
+            groupBy(iterator?: Iterator_<T, any>, context?: any): ChainedDictionary<any[]>;
+            groupBy(propertyName: string): ChainedDictionary<any[]>;
+            countBy(iterator?: Iterator_<T, any>, context?: any): ChainedDictionary<number>;
+            countBy(propertyName: string): ChainedDictionary<number>;
+            shuffle(): ChainedArray<T>;
+            toArray(): ChainedArray<T>;
+            size(): ChainedObject<number>;
+            first(): ChainedObject<T>;
+            first(count: number): ChainedArray<T>;
+            head(): ChainedObject<T>;
+            head(count: number): ChainedArray<T>;
+            take(): ChainedObject<T>;
+            take(count: number): ChainedArray<T>;
+            initial(): ChainedObject<T>;
+            initial(count: number): ChainedArray<T>;
+            last(): ChainedObject<T>;
+            last(count: number): ChainedArray<T>;
+            rest(index?: number): ChainedArray<T>;
+            compact(): ChainedArray<T>;
+            flatten<U>(shallow?: boolean): ChainedArray<U>;
+            without(...values: T[]): ChainedArray<T>;
+            union(...arrays: T[][]): ChainedArray<T>;
+            intersection(...arrays: T[][]): ChainedArray<T>;
+            difference(...others: T[][]): ChainedArray<T>;
+            uniq(isSorted?: boolean): ChainedArray<T>;
+            uniq<U>(isSorted: boolean, iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
+            unique(isSorted?: boolean): ChainedArray<T>;
+            unique<U>(isSorted: boolean, iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
+            zip(...arrays: any[][]): ChainedArray<any[]>;
+            object(): ChainedObject<any>;
+            object(values: any[]): ChainedObject<any>;
+            indexOf(value: T, isSorted?: boolean): ChainedObject<number>;
+            lastIndexOf(value: T, fromIndex?: number): ChainedObject<number>;
+            sortedIndex(obj: T, propertyName: string): ChainedObject<number>;
+            sortedIndex(obj: T, iterator?: Iterator_<T, any>, context?: any): ChainedObject<number>;
+            // Methods from Array
+            concat(...items: T[]): ChainedArray<T>;
+            join(separator?: string): ChainedObject<string>;
+            pop(): ChainedObject<T>;
+            push(...items: T[]): ChainedObject<number>;
+            reverse(): ChainedArray<T>;
+            shift(): ChainedObject<T>;
+            slice(start: number, end?: number): ChainedArray<T>;
+            sort(compareFn?: (a: T, b: T) => number): ChainedArray<T>;
+            splice(start: number): ChainedArray<T>;
+            splice(start: number, deleteCount: number, ...items: T[]): ChainedArray<T>;
+            unshift(...items: T[]): ChainedObject<number>;
+            // Methods from ChainedObject with promoted return types
+            extend(...sources: any[]): ChainedArray<T>;
+            pick(...keys: string[]): ChainedArray<T>;
+            omit(...keys: string[]): ChainedArray<T>;
+            defaults(...defaults: any[]): ChainedArray<T>;
+            clone(): ChainedArray<T>;
+            tap(interceptor: (object: T[]) => void): ChainedArray<T>;
+        }
+    
+        export interface ChainedDictionary<T> extends ChainedObject<Dictionary<T>> {
+            each(iterator: Iterator_<T, void>, context?: any): ChainedObject<void>;
+            forEach(iterator: Iterator_<T, void>, context?: any): ChainedObject<void>;
+            map<U>(iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
+            collect<U>(iterator: Iterator_<T, U>, context?: any): ChainedArray<U>;
+            reduce(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
+            reduce<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
+            foldl(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
+            foldl<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
+            inject(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
+            inject<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
+            reduceRight(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
+            reduceRight<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
+            foldr(iterator: Reducer<T, T>, initialValue?: T, context?: any): ChainedObject<T>;
+            foldr<U>(iterator: Reducer<T, U>, initialValue: U, context?: any): ChainedObject<U>;
+            find(iterator: Iterator_<T, boolean>, context?: any): ChainedObject<T>;
+            detect(iterator: Iterator_<T, boolean>, context?: any): ChainedObject<T>;
+            filter(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
+            select(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
+            where(properties: Object): ChainedArray<T>;
+            findWhere(properties: Object): ChainedObject<T>;
+            reject(iterator: Iterator_<T, boolean>, context?: any): ChainedArray<T>;
+            every(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
+            all(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
+            some(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
+            any(iterator?: Iterator_<T, boolean>, context?: any): ChainedObject<boolean>;
+            contains(value: T): ChainedObject<boolean>;
+            include(value: T): ChainedObject<boolean>;
+            invoke(methodName: string, ...args: any[]): ChainedArray<any>;
+            pluck(propertyName: string): ChainedArray<any>;
+            max(iterator?: Iterator_<T, any>, context?: any): ChainedObject<T>;
+            min(iterator?: Iterator_<T, any>, context?: any): ChainedObject<T>;
+            sortBy(iterator: Iterator_<T, any>, context?: any): ChainedArray<T>;
+            sortBy(propertyName: string): ChainedArray<T>;
+            // Should return ChainedDictionary<T[]>, but expansive recursion not allowed
+            groupBy(iterator?: Iterator_<T, any>, context?: any): ChainedDictionary<any[]>;
+            groupBy(propertyName: string): ChainedDictionary<any[]>;
+            countBy(iterator?: Iterator_<T, any>, context?: any): ChainedDictionary<number>;
+            countBy(propertyName: string): ChainedDictionary<number>;
+            shuffle(): ChainedArray<T>;
+            toArray(): ChainedArray<T>;
+            size(): ChainedObject<number>;
+            // Methods from ChainedObject with promoted return types
+            extend(...sources: any[]): ChainedDictionary<T>;
+            pick(...keys: string[]): ChainedDictionary<T>;
+            omit(...keys: string[]): ChainedDictionary<T>;
+            defaults(...defaults: any[]): ChainedDictionary<T>;
+            clone(): ChainedDictionary<T>;
+            tap(interceptor: (object: Dictionary<T>) => void): ChainedDictionary<T>;
+        }
+    
+        export interface TemplateSettings {
+            evaluate?: RegExp;
+            interpolate?: RegExp;
+            escape?: RegExp;
+            variable?: string;
+        }
+    
+        export interface Static {
+            <T>(list: T[]): WrappedArray<T>;
+            <T>(list: Dictionary<T>): WrappedDictionary<T>;
+            <T extends Function>(func: T): WrappedFunction<T>;
+            <T>(obj: T): WrappedObject<T>;
+    
+            chain<T>(list: T[]): ChainedArray<T>;
+            chain<T>(list: Dictionary<T>): ChainedDictionary<T>;
+            chain<T>(obj: T): ChainedObject<T>;
+    
+            each<T>(list: T[], iterator: Iterator_<T, void>, context?: any): void;
+            each<T>(list: Dictionary<T>, iterator: Iterator_<T, void>, context?: any): void;
+            forEach<T>(list: T[], iterator: Iterator_<T, void>, context?: any): void;
+            forEach<T>(list: Dictionary<T>, iterator: Iterator_<T, void>, context?: any): void;
+    
+            map<T, U>(list: T[], iterator: Iterator_<T, U>, context?: any): U[];
+            map<T, U>(list: Dictionary<T>, iterator: Iterator_<T, U>, context?: any): U[];
+            collect<T, U>(list: T[], iterator: Iterator_<T, U>, context?: any): U[];
+            collect<T, U>(list: Dictionary<T>, iterator: Iterator_<T, U>, context?: any): U[];
+    
+            reduce<T>(list: T[], iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            reduce<T, U>(list: T[], iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            reduce<T>(list: Dictionary<T>, iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            reduce<T, U>(list: Dictionary<T>, iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            foldl<T>(list: T[], iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            foldl<T, U>(list: T[], iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            foldl<T>(list: Dictionary<T>, iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            foldl<T, U>(list: Dictionary<T>, iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            inject<T>(list: T[], iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            inject<T, U>(list: T[], iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            inject<T>(list: Dictionary<T>, iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            inject<T, U>(list: Dictionary<T>, iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+    
+            reduceRight<T>(list: T[], iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            reduceRight<T, U>(list: T[], iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            reduceRight<T>(list: Dictionary<T>, iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            reduceRight<T, U>(list: Dictionary<T>, iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            foldr<T>(list: T[], iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            foldr<T, U>(list: T[], iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+            foldr<T>(list: Dictionary<T>, iterator: Reducer<T, T>, initialValue?: T, context?: any): T;
+            foldr<T, U>(list: Dictionary<T>, iterator: Reducer<T, U>, initialValue: U, context?: any): U;
+    
+            find<T>(list: T[], iterator: Iterator_<T, boolean>, context?: any): T;
+            find<T>(list: Dictionary<T>, iterator: Iterator_<T, boolean>, context?: any): T;
+            detect<T>(list: T[], iterator: Iterator_<T, boolean>, context?: any): T;
+            detect<T>(list: Dictionary<T>, iterator: Iterator_<T, boolean>, context?: any): T;
+    
+            filter<T>(list: T[], iterator: Iterator_<T, boolean>, context?: any): T[];
+            filter<T>(list: Dictionary<T>, iterator: Iterator_<T, boolean>, context?: any): T[];
+            select<T>(list: T[], iterator: Iterator_<T, boolean>, context?: any): T[];
+            select<T>(list: Dictionary<T>, iterator: Iterator_<T, boolean>, context?: any): T[];
+    
+            where<T>(list: T[], properties: Object): T[];
+            where<T>(list: Dictionary<T>, properties: Object): T[];
+    
+            findWhere<T>(list: T[], properties: Object): T;
+            findWhere<T>(list: Dictionary<T>, properties: Object): T;
+    
+            reject<T>(list: T[], iterator: Iterator_<T, boolean>, context?: any): T[];
+            reject<T>(list: Dictionary<T>, iterator: Iterator_<T, boolean>, context?: any): T[];
+    
+            every<T>(list: T[], iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            every<T>(list: Dictionary<T>, iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            all<T>(list: T[], iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            all<T>(list: Dictionary<T>, iterator?: Iterator_<T, boolean>, context?: any): boolean;
+    
+            some<T>(list: T[], iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            some<T>(list: Dictionary<T>, iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            any<T>(list: T[], iterator?: Iterator_<T, boolean>, context?: any): boolean;
+            any<T>(list: Dictionary<T>, iterator?: Iterator_<T, boolean>, context?: any): boolean;
+    
+            contains<T>(list: T[], value: T): boolean;
+            contains<T>(list: Dictionary<T>, value: T): boolean;
+            include<T>(list: T[], value: T): boolean;
+            include<T>(list: Dictionary<T>, value: T): boolean;
+    
+            invoke(list: any[], methodName: string, ...args: any[]): any[];
+            invoke(list: Dictionary<any>, methodName: string, ...args: any[]): any[];
+    
+            pluck(list: any[], propertyName: string): any[];
+            pluck(list: Dictionary<any>, propertyName: string): any[];
+    
+            max<T>(list: T[], iterator?: Iterator_<T, any>, context?: any): T;
+            max<T>(list: Dictionary<T>, iterator?: Iterator_<T, any>, context?: any): T;
+    
+            min<T>(list: T[], iterator?: Iterator_<T, any>, context?: any): T;
+            min<T>(list: Dictionary<T>, iterator?: Iterator_<T, any>, context?: any): T;
+    
+            sortBy<T>(list: T[], iterator: Iterator_<T, any>, context?: any): T[];
+            sortBy<T>(list: Dictionary<T>, iterator: Iterator_<T, any>, context?: any): T[];
+            sortBy<T>(list: T[], propertyName: string): T[];
+            sortBy<T>(list: Dictionary<T>, propertyName: string): T[];
+    
+            groupBy<T>(list: T[], iterator?: Iterator_<T, any>, context?: any): Dictionary<T[]>;
+            groupBy<T>(list: Dictionary<T>, iterator?: Iterator_<T, any>, context?: any): Dictionary<T[]>;
+            groupBy<T>(list: T[], propertyName: string): Dictionary<T[]>;
+            groupBy<T>(list: Dictionary<T>, propertyName: string): Dictionary<T[]>;
+    
+            countBy<T>(list: T[], iterator?: Iterator_<T, any>, context?: any): Dictionary<number>;
+            countBy<T>(list: Dictionary<T>, iterator?: Iterator_<T, any>, context?: any): Dictionary<number>;
+            countBy<T>(list: T[], propertyName: string): Dictionary<number>;
+            countBy<T>(list: Dictionary<T>, propertyName: string): Dictionary<number>;
+    
+            shuffle<T>(list: T[]): T[];
+            shuffle<T>(list: Dictionary<T>): T[];
+    
+            toArray<T>(list: T[]): T[];
+            toArray<T>(list: Dictionary<T>): T[];
+    
+            size<T>(list: T[]): number;
+            size<T>(list: Dictionary<T>): number;
+    
+            first<T>(list: T[]): T;
+            first<T>(list: T[], count: number): T[];
+            head<T>(list: T[]): T;
+            head<T>(list: T[], count: number): T[];
+            take<T>(list: T[]): T;
+            take<T>(list: T[], count: number): T[];
+    
+            initial<T>(list: T[]): T;
+            initial<T>(list: T[], count: number): T[];
+    
+            last<T>(list: T[]): T;
+            last<T>(list: T[], count: number): T[];
+    
+            rest<T>(list: T[], index?: number): T[];
+    
+            compact<T>(list: T[]): T[];
+    
+            flatten<T>(list: T[][]): T[];
+            flatten<T>(array: any[], shallow?: boolean): T[];
+    
+            without<T>(list: T[], ...values: T[]): T[];
+    
+            union<T>(...arrays: T[][]): T[];
+    
+            intersection<T>(...arrays: T[][]): T[];
+    
+            difference<T>(list: T[], ...others: T[][]): T[];
+    
+            uniq<T>(list: T[], isSorted?: boolean): T[];
+            uniq<T, U>(list: T[], isSorted: boolean, iterator: Iterator_<T, U>, context?: any): U[];
+            unique<T>(list: T[], isSorted?: boolean): T[];
+            unique<T, U>(list: T[], isSorted: boolean, iterator: Iterator_<T, U>, context?: any): U[];
+    
+            zip<T0, T1>(a0: T0[], a1: T1[]): Tuple2<T0, T1>[];
+            zip<T0, T1, T2>(a0: T0[], a1: T1[], a2: T2[]): Tuple3<T0, T1, T2>[];
+            zip<T0, T1, T2, T3>(a0: T0[], a1: T1[], a2: T2[], a3: T3[]): Tuple4<T0, T1, T2, T3>[];
+            zip(...arrays: any[][]): any[][];
+    
+            object(list: any[][]): any;
+            object(keys: string[], values: any[]): any;
+    
+            indexOf<T>(list: T[], value: T, isSorted?: boolean): number;
+    
+            lastIndexOf<T>(list: T[], value: T, fromIndex?: number): number;
+    
+            sortedIndex<T>(list: T[], obj: T, propertyName: string): number;
+            sortedIndex<T>(list: T[], obj: T, iterator?: Iterator_<T, any>, context?: any): number;
+    
+            range(stop: number): number[];
+            range(start: number, stop: number, step?: number): number[];
+    
+            bind<T extends Function>(func: T, object: any): T;
+            bind(func: Function, object: any, ...args: any[]): Function;
+    
+            bindAll<T>(object: T, ...methodNames: string[]): T;
+    
+            partial(func: Function, ...args: any[]): Function;
+    
+            memoize<T extends Function>(func: T, hashFunction?: Function): T;
+    
+            delay(func: Function, wait: number, ...args: any[]): number;
+    
+            defer(func: Function, ...args: any[]): number;
+    
+            throttle<T extends Function>(func: T, wait: number): T;
+    
+            debounce<T extends Function>(func: T, wait: number, immediate?: boolean): T;
+    
+            once<T extends Function>(func: T): T;
+    
+            after<T extends Function>(count: number, func: T): T;
+    
+            wrap<T extends Function>(func: T, wrapper: (func: T, ...args: any[]) => any): T;
+    
+            compose(...funcs: Function[]): Function;
+    
+            keys(object: any): string[];
+    
+            values(object: any): any[];
+    
+            pairs(object: any): any[][];
+    
+            invert(object: any): any;
+    
+            functions(object: any): string[];
+            methods(object: any): string[];
+    
+            extend<T>(destination: T, ...sources: any[]): T;
+    
+            pick<T>(object: T, ...keys: string[]): T;
+    
+            omit<T>(object: T, ...keys: string[]): T;
+    
+            defaults<T>(object: T, ...defaults: any[]): T;
+    
+            clone<T>(object: T): T;
+    
+            tap<T>(object: T, interceptor: (object: T) => void): T;
+    
+            has(object: any, key: string): boolean;
+    
+            isEqual<T>(object: T, other: T): boolean;
+    
+            isEmpty(object: any): boolean;
+            isElement(object: any): boolean;
+            isArray(object: any): boolean;
+            isObject(value: any): boolean;
+            isArguments(object: any): boolean;
+            isFunction(object: any): boolean;
+            isString(object: any): boolean;
+            isNumber(object: any): boolean;
+            isFinite(object: any): boolean;
+            isBoolean(object: any): boolean;
+            isDate(object: any): boolean;
+            isRegExp(object: any): boolean;
+            isNaN(object: any): boolean;
+            isNull(object: any): boolean;
+            isUndefined(value: any): boolean;
+    
+            noConflict(): Static;
+    
+            identity<T>(value: T): T;
+    
+            times<U>(n: number, iterator: Iterator_<number, U>, context?: any): U[];
+    
+            random(max: number): number;
+            random(min: number, max: number): number;
+    
+            mixin(object: any): void;
+    
+            uniqueId(): number;
+            uniqueId(prefix: string): string;
+    
+            escape(s: string): string;
+    
+            unescape(s: string): string;
+    
+            result(object: any, property: string): any;
+    
+            templateSettings: TemplateSettings;
+    
+            template(templateString: string): (data: any) => string;
+            template(templateString: string, data: any, settings?: TemplateSettings): string;
+        }
+    }
+    
+    declare var _: Underscore.Static;
+    
\ No newline at end of file
diff --git a/tests/cases/compiler/noStrictGenericChecks.ts b/tests/cases/compiler/noStrictGenericChecks.ts
new file mode 100644
index 0000000000000..55593feef75c5
--- /dev/null
+++ b/tests/cases/compiler/noStrictGenericChecks.ts
@@ -0,0 +1,9 @@
+// @noStrictGenericChecks: true
+
+type A = <T, U>(x: T, y: U) => [T, U];
+type B = <S>(x: S, y: S) => [S, S];
+
+function f(a: A, b: B) {
+    a = b;  // Error disabled here
+    b = a;  // Ok
+}
diff --git a/tests/cases/fourslash/genericTypeArgumentInference1.ts b/tests/cases/fourslash/genericTypeArgumentInference1.ts
index 5d4d38c4865e6..7008e00f7ab64 100644
--- a/tests/cases/fourslash/genericTypeArgumentInference1.ts
+++ b/tests/cases/fourslash/genericTypeArgumentInference1.ts
@@ -2,7 +2,7 @@
 
 ////module Underscore {
 ////    export interface Iterator<T, U> {
-////        <T,U>(value: T, index: any, list: any): U;
+////        (value: T, index: any, list: any): U;
 ////    }
 ////
 ////    export interface Static {
@@ -12,7 +12,7 @@
 ////}
 ////
 ////declare var _: Underscore.Static;
-////var /*1*/r = _./*11*/all([true, 1, null, 'yes'], _.identity);
+////var /*1*/r = _./*11*/all([true, 1, null, 'yes'], x => !x);
 ////var /*2*/r2 = _./*21*/all([true], _.identity);
 ////var /*3*/r3 = _./*31*/all([], _.identity);
 ////var /*4*/r4 = _./*41*/all([<any>true], _.identity);
diff --git a/tests/cases/fourslash/genericTypeArgumentInference2.ts b/tests/cases/fourslash/genericTypeArgumentInference2.ts
deleted file mode 100644
index a93e5ac6ea5aa..0000000000000
--- a/tests/cases/fourslash/genericTypeArgumentInference2.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/// <reference path='fourslash.ts'/>
-
-////module Underscore {
-////    export interface Iterator<T, U> {
-////        (value: T, index: any, list: any): U;
-////    }
-////
-////    export interface Static {
-////        all<T>(list: T[], iterator?: Iterator<T, boolean>, context?: any): T;
-////        identity<T>(value: T): T;
-////    }
-////}
-////
-////declare var _: Underscore.Static;
-////var /*1*/r = _./*11*/all([true, 1, null, 'yes'], _.identity);
-////var /*2*/r2 = _./*21*/all([true], _.identity);
-////var /*3*/r3 = _./*31*/all([], _.identity);
-////var /*4*/r4 = _./*41*/all([<any>true], _.identity);
-
-verify.quickInfos({
-    1: "var r: string | number | boolean",
-    11: "(method) Underscore.Static.all<string | number | boolean>(list: (string | number | boolean)[], iterator?: Underscore.Iterator<string | number | boolean, boolean>, context?: any): string | number | boolean",
-
-    2: "var r2: boolean",
-    21: "(method) Underscore.Static.all<boolean>(list: boolean[], iterator?: Underscore.Iterator<boolean, boolean>, context?: any): boolean",
-
-    3: "var r3: any",
-    31: "(method) Underscore.Static.all<any>(list: any[], iterator?: Underscore.Iterator<any, boolean>, context?: any): any",
-
-    4: "var r4: any",
-    41: "(method) Underscore.Static.all<any>(list: any[], iterator?: Underscore.Iterator<any, boolean>, context?: any): any"
-});
-verify.noErrors();