diff --git a/tests/baselines/reference/typeVariableTypeGuards.js b/tests/baselines/reference/typeVariableTypeGuards.js
new file mode 100644
index 00000000000..c1337561b32
--- /dev/null
+++ b/tests/baselines/reference/typeVariableTypeGuards.js
@@ -0,0 +1,147 @@
+//// [typeVariableTypeGuards.ts]
+// Repro from #14091
+
+interface Foo {
+ foo(): void
+}
+
+class A
> {
+ props: Readonly
+ doSomething() {
+ this.props.foo && this.props.foo()
+ }
+}
+
+// Repro from #14415
+
+interface Banana {
+ color: 'yellow';
+}
+
+class Monkey {
+ a: T;
+ render() {
+ if (this.a) {
+ this.a.color;
+ }
+ }
+}
+
+interface BigBanana extends Banana {
+}
+
+class BigMonkey extends Monkey {
+ render() {
+ if (this.a) {
+ this.a.color;
+ }
+ }
+}
+
+// Another repro
+
+type Item = {
+ (): string;
+ x: string;
+}
+
+function f1(obj: T) {
+ if (obj) {
+ obj.x;
+ obj["x"];
+ obj();
+ }
+}
+
+function f2(obj: T | undefined) {
+ if (obj) {
+ obj.x;
+ obj["x"];
+ obj();
+ }
+}
+
+function f3(obj: T | null) {
+ if (obj) {
+ obj.x;
+ obj["x"];
+ obj();
+ }
+}
+
+function f4(obj: T | undefined, x: number) {
+ if (obj) {
+ obj[x].length;
+ }
+}
+
+
+//// [typeVariableTypeGuards.js]
+"use strict";
+// Repro from #14091
+var __extends = (this && this.__extends) || (function () {
+ var extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+var A = (function () {
+ function A() {
+ }
+ A.prototype.doSomething = function () {
+ this.props.foo && this.props.foo();
+ };
+ return A;
+}());
+var Monkey = (function () {
+ function Monkey() {
+ }
+ Monkey.prototype.render = function () {
+ if (this.a) {
+ this.a.color;
+ }
+ };
+ return Monkey;
+}());
+var BigMonkey = (function (_super) {
+ __extends(BigMonkey, _super);
+ function BigMonkey() {
+ return _super !== null && _super.apply(this, arguments) || this;
+ }
+ BigMonkey.prototype.render = function () {
+ if (this.a) {
+ this.a.color;
+ }
+ };
+ return BigMonkey;
+}(Monkey));
+function f1(obj) {
+ if (obj) {
+ obj.x;
+ obj["x"];
+ obj();
+ }
+}
+function f2(obj) {
+ if (obj) {
+ obj.x;
+ obj["x"];
+ obj();
+ }
+}
+function f3(obj) {
+ if (obj) {
+ obj.x;
+ obj["x"];
+ obj();
+ }
+}
+function f4(obj, x) {
+ if (obj) {
+ obj[x].length;
+ }
+}
diff --git a/tests/baselines/reference/typeVariableTypeGuards.symbols b/tests/baselines/reference/typeVariableTypeGuards.symbols
new file mode 100644
index 00000000000..e0c21e12adb
--- /dev/null
+++ b/tests/baselines/reference/typeVariableTypeGuards.symbols
@@ -0,0 +1,202 @@
+=== tests/cases/compiler/typeVariableTypeGuards.ts ===
+// Repro from #14091
+
+interface Foo {
+>Foo : Symbol(Foo, Decl(typeVariableTypeGuards.ts, 0, 0))
+
+ foo(): void
+>foo : Symbol(Foo.foo, Decl(typeVariableTypeGuards.ts, 2, 15))
+}
+
+class A> {
+>A : Symbol(A, Decl(typeVariableTypeGuards.ts, 4, 1))
+>P : Symbol(P, Decl(typeVariableTypeGuards.ts, 6, 8))
+>Partial : Symbol(Partial, Decl(lib.d.ts, --, --))
+>Foo : Symbol(Foo, Decl(typeVariableTypeGuards.ts, 0, 0))
+
+ props: Readonly
+>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33))
+>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --))
+>P : Symbol(P, Decl(typeVariableTypeGuards.ts, 6, 8))
+
+ doSomething() {
+>doSomething : Symbol(A.doSomething, Decl(typeVariableTypeGuards.ts, 7, 22))
+
+ this.props.foo && this.props.foo()
+>this.props.foo : Symbol(foo)
+>this.props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33))
+>this : Symbol(A, Decl(typeVariableTypeGuards.ts, 4, 1))
+>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33))
+>foo : Symbol(foo)
+>this.props.foo : Symbol(foo)
+>this.props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33))
+>this : Symbol(A, Decl(typeVariableTypeGuards.ts, 4, 1))
+>props : Symbol(A.props, Decl(typeVariableTypeGuards.ts, 6, 33))
+>foo : Symbol(foo)
+ }
+}
+
+// Repro from #14415
+
+interface Banana {
+>Banana : Symbol(Banana, Decl(typeVariableTypeGuards.ts, 11, 1))
+
+ color: 'yellow';
+>color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18))
+}
+
+class Monkey {
+>Monkey : Symbol(Monkey, Decl(typeVariableTypeGuards.ts, 17, 1))
+>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 19, 13))
+>Banana : Symbol(Banana, Decl(typeVariableTypeGuards.ts, 11, 1))
+
+ a: T;
+>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
+>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 19, 13))
+
+ render() {
+>render : Symbol(Monkey.render, Decl(typeVariableTypeGuards.ts, 20, 9))
+
+ if (this.a) {
+>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
+>this : Symbol(Monkey, Decl(typeVariableTypeGuards.ts, 17, 1))
+>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
+
+ this.a.color;
+>this.a.color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18))
+>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
+>this : Symbol(Monkey, Decl(typeVariableTypeGuards.ts, 17, 1))
+>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
+>color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18))
+ }
+ }
+}
+
+interface BigBanana extends Banana {
+>BigBanana : Symbol(BigBanana, Decl(typeVariableTypeGuards.ts, 26, 1))
+>Banana : Symbol(Banana, Decl(typeVariableTypeGuards.ts, 11, 1))
+}
+
+class BigMonkey extends Monkey {
+>BigMonkey : Symbol(BigMonkey, Decl(typeVariableTypeGuards.ts, 29, 1))
+>Monkey : Symbol(Monkey, Decl(typeVariableTypeGuards.ts, 17, 1))
+>BigBanana : Symbol(BigBanana, Decl(typeVariableTypeGuards.ts, 26, 1))
+
+ render() {
+>render : Symbol(BigMonkey.render, Decl(typeVariableTypeGuards.ts, 31, 43))
+
+ if (this.a) {
+>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
+>this : Symbol(BigMonkey, Decl(typeVariableTypeGuards.ts, 29, 1))
+>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
+
+ this.a.color;
+>this.a.color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18))
+>this.a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
+>this : Symbol(BigMonkey, Decl(typeVariableTypeGuards.ts, 29, 1))
+>a : Symbol(Monkey.a, Decl(typeVariableTypeGuards.ts, 19, 44))
+>color : Symbol(Banana.color, Decl(typeVariableTypeGuards.ts, 15, 18))
+ }
+ }
+}
+
+// Another repro
+
+type Item = {
+>Item : Symbol(Item, Decl(typeVariableTypeGuards.ts, 37, 1))
+
+ (): string;
+ x: string;
+>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15))
+}
+
+function f1(obj: T) {
+>f1 : Symbol(f1, Decl(typeVariableTypeGuards.ts, 44, 1))
+>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 46, 12))
+>Item : Symbol(Item, Decl(typeVariableTypeGuards.ts, 37, 1))
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 46, 40))
+>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 46, 12))
+
+ if (obj) {
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 46, 40))
+
+ obj.x;
+>obj.x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15))
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 46, 40))
+>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15))
+
+ obj["x"];
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 46, 40))
+>"x" : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15))
+
+ obj();
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 46, 40))
+ }
+}
+
+function f2(obj: T | undefined) {
+>f2 : Symbol(f2, Decl(typeVariableTypeGuards.ts, 52, 1))
+>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 54, 12))
+>Item : Symbol(Item, Decl(typeVariableTypeGuards.ts, 37, 1))
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 54, 40))
+>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 54, 12))
+
+ if (obj) {
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 54, 40))
+
+ obj.x;
+>obj.x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15))
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 54, 40))
+>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15))
+
+ obj["x"];
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 54, 40))
+>"x" : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15))
+
+ obj();
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 54, 40))
+ }
+}
+
+function f3(obj: T | null) {
+>f3 : Symbol(f3, Decl(typeVariableTypeGuards.ts, 60, 1))
+>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 62, 12))
+>Item : Symbol(Item, Decl(typeVariableTypeGuards.ts, 37, 1))
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 62, 40))
+>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 62, 12))
+
+ if (obj) {
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 62, 40))
+
+ obj.x;
+>obj.x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15))
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 62, 40))
+>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15))
+
+ obj["x"];
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 62, 40))
+>"x" : Symbol(x, Decl(typeVariableTypeGuards.ts, 42, 15))
+
+ obj();
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 62, 40))
+ }
+}
+
+function f4(obj: T | undefined, x: number) {
+>f4 : Symbol(f4, Decl(typeVariableTypeGuards.ts, 68, 1))
+>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 70, 12))
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 70, 44))
+>T : Symbol(T, Decl(typeVariableTypeGuards.ts, 70, 12))
+>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 70, 63))
+
+ if (obj) {
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 70, 44))
+
+ obj[x].length;
+>obj[x].length : Symbol(String.length, Decl(lib.d.ts, --, --))
+>obj : Symbol(obj, Decl(typeVariableTypeGuards.ts, 70, 44))
+>x : Symbol(x, Decl(typeVariableTypeGuards.ts, 70, 63))
+>length : Symbol(String.length, Decl(lib.d.ts, --, --))
+ }
+}
+
diff --git a/tests/baselines/reference/typeVariableTypeGuards.types b/tests/baselines/reference/typeVariableTypeGuards.types
new file mode 100644
index 00000000000..a20129440a0
--- /dev/null
+++ b/tests/baselines/reference/typeVariableTypeGuards.types
@@ -0,0 +1,212 @@
+=== tests/cases/compiler/typeVariableTypeGuards.ts ===
+// Repro from #14091
+
+interface Foo {
+>Foo : Foo
+
+ foo(): void
+>foo : () => void
+}
+
+class A> {
+>A : A
+>P : P
+>Partial : Partial
+>Foo : Foo
+
+ props: Readonly
+>props : Readonly
+>Readonly : Readonly
+>P : P
+
+ doSomething() {
+>doSomething : () => void
+
+ this.props.foo && this.props.foo()
+>this.props.foo && this.props.foo() : void
+>this.props.foo : P["foo"]
+>this.props : Readonly
+>this : this
+>props : Readonly
+>foo : P["foo"]
+>this.props.foo() : void
+>this.props.foo : () => void
+>this.props : Readonly
+>this : this
+>props : Readonly
+>foo : () => void
+ }
+}
+
+// Repro from #14415
+
+interface Banana {
+>Banana : Banana
+
+ color: 'yellow';
+>color : "yellow"
+}
+
+class Monkey {
+>Monkey : Monkey
+>T : T
+>Banana : Banana
+
+ a: T;
+>a : T
+>T : T
+
+ render() {
+>render : () => void
+
+ if (this.a) {
+>this.a : T
+>this : this
+>a : T
+
+ this.a.color;
+>this.a.color : "yellow"
+>this.a : Banana
+>this : this
+>a : Banana
+>color : "yellow"
+ }
+ }
+}
+
+interface BigBanana extends Banana {
+>BigBanana : BigBanana
+>Banana : Banana
+}
+
+class BigMonkey extends Monkey {
+>BigMonkey : BigMonkey
+>Monkey : Monkey
+>BigBanana : BigBanana
+
+ render() {
+>render : () => void
+
+ if (this.a) {
+>this.a : BigBanana
+>this : this
+>a : BigBanana
+
+ this.a.color;
+>this.a.color : "yellow"
+>this.a : BigBanana
+>this : this
+>a : BigBanana
+>color : "yellow"
+ }
+ }
+}
+
+// Another repro
+
+type Item = {
+>Item : Item
+
+ (): string;
+ x: string;
+>x : string
+}
+
+function f1(obj: T) {
+>f1 : (obj: T) => void
+>T : T
+>Item : Item
+>obj : T
+>T : T
+
+ if (obj) {
+>obj : T
+
+ obj.x;
+>obj.x : string
+>obj : Item
+>x : string
+
+ obj["x"];
+>obj["x"] : string
+>obj : Item
+>"x" : "x"
+
+ obj();
+>obj() : string
+>obj : Item
+ }
+}
+
+function f2(obj: T | undefined) {
+>f2 : (obj: T | undefined) => void
+>T : T
+>Item : Item
+>obj : T | undefined
+>T : T
+
+ if (obj) {
+>obj : T | undefined
+
+ obj.x;
+>obj.x : string
+>obj : Item
+>x : string
+
+ obj["x"];
+>obj["x"] : string
+>obj : Item
+>"x" : "x"
+
+ obj();
+>obj() : string
+>obj : Item
+ }
+}
+
+function f3(obj: T | null) {
+>f3 : (obj: T | null) => void
+>T : T
+>Item : Item
+>obj : T | null
+>T : T
+>null : null
+
+ if (obj) {
+>obj : T | null
+
+ obj.x;
+>obj.x : string
+>obj : Item
+>x : string
+
+ obj["x"];
+>obj["x"] : string
+>obj : Item
+>"x" : "x"
+
+ obj();
+>obj() : string
+>obj : Item
+ }
+}
+
+function f4(obj: T | undefined, x: number) {
+>f4 : (obj: T | undefined, x: number) => void
+>T : T
+>obj : T | undefined
+>T : T
+>x : number
+
+ if (obj) {
+>obj : T | undefined
+
+ obj[x].length;
+>obj[x].length : number
+>obj[x] : string
+>obj : string[]
+>x : number
+>length : number
+ }
+}
+
diff --git a/tests/cases/compiler/typeVariableTypeGuards.ts b/tests/cases/compiler/typeVariableTypeGuards.ts
new file mode 100644
index 00000000000..a962fd786c7
--- /dev/null
+++ b/tests/cases/compiler/typeVariableTypeGuards.ts
@@ -0,0 +1,77 @@
+// @strict: true
+
+// Repro from #14091
+
+interface Foo {
+ foo(): void
+}
+
+class A> {
+ props: Readonly
+ doSomething() {
+ this.props.foo && this.props.foo()
+ }
+}
+
+// Repro from #14415
+
+interface Banana {
+ color: 'yellow';
+}
+
+class Monkey {
+ a: T;
+ render() {
+ if (this.a) {
+ this.a.color;
+ }
+ }
+}
+
+interface BigBanana extends Banana {
+}
+
+class BigMonkey extends Monkey {
+ render() {
+ if (this.a) {
+ this.a.color;
+ }
+ }
+}
+
+// Another repro
+
+type Item = {
+ (): string;
+ x: string;
+}
+
+function f1(obj: T) {
+ if (obj) {
+ obj.x;
+ obj["x"];
+ obj();
+ }
+}
+
+function f2(obj: T | undefined) {
+ if (obj) {
+ obj.x;
+ obj["x"];
+ obj();
+ }
+}
+
+function f3(obj: T | null) {
+ if (obj) {
+ obj.x;
+ obj["x"];
+ obj();
+ }
+}
+
+function f4(obj: T | undefined, x: number) {
+ if (obj) {
+ obj[x].length;
+ }
+}