From 9f88c2f2ca0fd42dc9e16baf7eae240ffc380def Mon Sep 17 00:00:00 2001
From: Evgeny Muryshkin <evmuryshkin@gmail.com>
Date: Sat, 22 Dec 2018 18:23:31 +1100
Subject: [PATCH 1/3] Proposed fix for issue 29114

---
 src/compiler/checker.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 23c5568f2e5f4..e076d912b16e3 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -7935,7 +7935,7 @@ namespace ts {
                 const baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
                 const circularityMapper = createTypeMapper(typeParameters!, map(typeParameters!, () => baseDefaultType));
                 for (let i = numTypeArguments; i < numTypeParameters; i++) {
-                    result[i] = instantiateType(getConstraintFromTypeParameter(typeParameters![i]) || baseDefaultType, circularityMapper);
+                    result[i] = instantiateType(getConstraintOfTypeParameter(typeParameters![i]) || baseDefaultType, circularityMapper);
                 }
                 for (let i = numTypeArguments; i < numTypeParameters; i++) {
                     const mapper = createTypeMapper(typeParameters!, result);

From b2dc1b3d3154e6bcde50800dafbd559240bf173e Mon Sep 17 00:00:00 2001
From: Anders Hejlsberg <andersh@microsoft.com>
Date: Tue, 25 Dec 2018 08:22:11 -1000
Subject: [PATCH 2/3] Add regression test

---
 .../typeArgumentDefaultUsesConstraintOnCircularDefault.ts   | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts b/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts
index b8361ea571496..c8f5e2a26cb61 100644
--- a/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts
+++ b/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts
@@ -3,3 +3,9 @@ type Test<T extends string = T> = { value: T };
 let zz: Test = { foo: "abc" };  // should error on comparison with Test<string>
 
 let zzy: Test = { value: {} };  // should error
+
+// Simplified repro from #28873
+
+class C1<T extends C1 = any> {}  // Error, circular constraint
+
+class C2<T extends C2<any> = any> {}

From ebb66dffa257c3ce70aded3871874306eb45e602 Mon Sep 17 00:00:00 2001
From: Anders Hejlsberg <andersh@microsoft.com>
Date: Tue, 25 Dec 2018 08:22:21 -1000
Subject: [PATCH 3/3] Accept new baselines

---
 ...ltUsesConstraintOnCircularDefault.errors.txt | 11 ++++++++++-
 ...entDefaultUsesConstraintOnCircularDefault.js | 17 +++++++++++++++++
 ...faultUsesConstraintOnCircularDefault.symbols | 12 ++++++++++++
 ...DefaultUsesConstraintOnCircularDefault.types |  8 ++++++++
 4 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt
index 71e3ef046277a..51ba5e5d43bef 100644
--- a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt
+++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt
@@ -1,9 +1,10 @@
 tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(3,18): error TS2322: Type '{ foo: string; }' is not assignable to type 'Test<string>'.
   Object literal may only specify known properties, and 'foo' does not exist in type 'Test<string>'.
 tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(5,19): error TS2322: Type '{}' is not assignable to type 'string'.
+tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(9,20): error TS2313: Type parameter 'T' has a circular constraint.
 
 
-==== tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts (2 errors) ====
+==== tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts (3 errors) ====
     type Test<T extends string = T> = { value: T };
     
     let zz: Test = { foo: "abc" };  // should error on comparison with Test<string>
@@ -15,4 +16,12 @@ tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(5,19)
                       ~~~~~
 !!! error TS2322: Type '{}' is not assignable to type 'string'.
 !!! related TS6500 tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts:1:37: The expected type comes from property 'value' which is declared here on type 'Test<string>'
+    
+    // Simplified repro from #28873
+    
+    class C1<T extends C1 = any> {}  // Error, circular constraint
+                       ~~
+!!! error TS2313: Type parameter 'T' has a circular constraint.
+    
+    class C2<T extends C2<any> = any> {}
     
\ No newline at end of file
diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js
index 296a0063fe270..58d208c7cc8ba 100644
--- a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js
+++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js
@@ -4,8 +4,25 @@ type Test<T extends string = T> = { value: T };
 let zz: Test = { foo: "abc" };  // should error on comparison with Test<string>
 
 let zzy: Test = { value: {} };  // should error
+
+// Simplified repro from #28873
+
+class C1<T extends C1 = any> {}  // Error, circular constraint
+
+class C2<T extends C2<any> = any> {}
 
 
 //// [typeArgumentDefaultUsesConstraintOnCircularDefault.js]
 var zz = { foo: "abc" }; // should error on comparison with Test<string>
 var zzy = { value: {} }; // should error
+// Simplified repro from #28873
+var C1 = /** @class */ (function () {
+    function C1() {
+    }
+    return C1;
+}()); // Error, circular constraint
+var C2 = /** @class */ (function () {
+    function C2() {
+    }
+    return C2;
+}());
diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols
index 2181e34188964..94cdd377548ab 100644
--- a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols
+++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols
@@ -16,3 +16,15 @@ let zzy: Test = { value: {} };  // should error
 >Test : Symbol(Test, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 0))
 >value : Symbol(value, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 4, 17))
 
+// Simplified repro from #28873
+
+class C1<T extends C1 = any> {}  // Error, circular constraint
+>C1 : Symbol(C1, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 4, 30))
+>T : Symbol(T, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 8, 9))
+>C1 : Symbol(C1, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 4, 30))
+
+class C2<T extends C2<any> = any> {}
+>C2 : Symbol(C2, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 8, 31))
+>T : Symbol(T, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 10, 9))
+>C2 : Symbol(C2, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 8, 31))
+
diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types
index 7c0d469da4619..aa39f08d234d9 100644
--- a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types
+++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types
@@ -15,3 +15,11 @@ let zzy: Test = { value: {} };  // should error
 >value : {}
 >{} : {}
 
+// Simplified repro from #28873
+
+class C1<T extends C1 = any> {}  // Error, circular constraint
+>C1 : C1<T>
+
+class C2<T extends C2<any> = any> {}
+>C2 : C2<T>
+