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; + } +}