Change type narrowing for optional properties

This commit is contained in:
IdeaHunter 2017-04-21 02:03:25 +03:00
parent a5d6be150b
commit 069f73d0f2
8 changed files with 517 additions and 360 deletions

View file

@ -12722,10 +12722,30 @@ namespace ts {
return type;
}
function isTypePresencePossible(type: Type, propName: string, shouldHaveProperty: boolean) {
const prop = getPropertyOfType(type, propName);
if (!prop) {
// if there is NO property:
// - but we assume type SHOULD have it then presence of object of following type IS NOT possible
// - and we assume type SHOULD NOT have it then presence of object of following type IS possible
return !shouldHaveProperty;
} else if (prop.flags & SymbolFlags.Optional) {
// if there is an optional property:
// - and we assume type SHOULD have it then presence of object of following type IS possible
// - but assume type SHOULD NOT have it then presence of object of following type IS still possible
return true;
} else /* if (prop.flags & SymbolFlags.Required) */ {
// if there is a required property:
// - and we assume type SHOULD have it then presence of object of following type IS possible
// - but we assume type SHOULD NOT have it then presence of object of following type IS NOT possible
return shouldHaveProperty;
}
}
function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
if ((type.flags & (TypeFlags.Union | TypeFlags.Object)) || (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType)) {
const propName = literal.text;
return filterType(type, t => !!getPropertyOfType(t, propName) === assumeTrue);
return filterType(type, t => isTypePresencePossible(t, propName, /* shouldHaveProperty */ assumeTrue));
}
return type;
}

View file

@ -2,6 +2,8 @@ tests/cases/compiler/inKeywordTypeguard.ts(6,11): error TS2339: Property 'b' doe
tests/cases/compiler/inKeywordTypeguard.ts(8,11): error TS2339: Property 'a' does not exist on type 'B'.
tests/cases/compiler/inKeywordTypeguard.ts(14,11): error TS2339: Property 'b' does not exist on type 'A'.
tests/cases/compiler/inKeywordTypeguard.ts(16,11): error TS2339: Property 'a' does not exist on type 'B'.
tests/cases/compiler/inKeywordTypeguard.ts(27,11): error TS2339: Property 'b' does not exist on type 'AWithOptionalProp | BWithOptionalProp'.
Property 'b' does not exist on type 'AWithOptionalProp'.
tests/cases/compiler/inKeywordTypeguard.ts(42,11): error TS2339: Property 'b' does not exist on type 'AWithMethod'.
tests/cases/compiler/inKeywordTypeguard.ts(49,11): error TS2339: Property 'a' does not exist on type 'never'.
tests/cases/compiler/inKeywordTypeguard.ts(50,11): error TS2339: Property 'b' does not exist on type 'never'.
@ -19,7 +21,7 @@ tests/cases/compiler/inKeywordTypeguard.ts(84,39): error TS2339: Property 'a' do
tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' does not exist on type 'never'.
==== tests/cases/compiler/inKeywordTypeguard.ts (16 errors) ====
==== tests/cases/compiler/inKeywordTypeguard.ts (17 errors) ====
class A { a: string; }
class B { b: string; }
@ -47,23 +49,26 @@ tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' do
}
}
class AOpt { a?: string }
class BOpn { b?: string }
class AWithOptionalProp { a?: string; }
class BWithOptionalProp { b?: string; }
function positiveTestClassesWithOptionalProperties(x: AOpt | BOpn) {
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
if ("a" in x) {
x.a = "1";
} else {
x.b = "1";
~
!!! error TS2339: Property 'b' does not exist on type 'AWithOptionalProp | BWithOptionalProp'.
!!! error TS2339: Property 'b' does not exist on type 'AWithOptionalProp'.
}
}
class AWithMethod {
a(): string { return "" }
a(): string { return ""; }
}
class BWithMethod {
b(): string { return "" }
b(): string { return ""; }
}
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
@ -96,8 +101,8 @@ tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' do
}
}
class C { a: string }
class D { a: string }
class C { a: string; }
class D { a: string; }
function negativeMultipleClassesTest(x: A | B | C | D) {
if ("a" in x) {
@ -112,9 +117,9 @@ tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' do
}
}
class ClassWithProp { prop: A | B }
class ClassWithUnionProp { prop: A | B }
function negativePropTest(x: ClassWithProp) {
function negativePropTest(x: ClassWithUnionProp) {
if ("a" in x.prop) {
let y: string = x.prop.b;
~
@ -129,7 +134,7 @@ tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' do
class NegativeClassTest {
protected prop: A | B;
inThis() {
if ('a' in this.prop) {
if ("a" in this.prop) {
let z: number = this.prop.b;
~
!!! error TS2339: Property 'b' does not exist on type 'A'.
@ -144,7 +149,7 @@ tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' do
class UnreachableCodeDetection {
a: string;
inThis() {
if ('a' in this) {
if ("a" in this) {
} else {
let y = this.a;
~

View file

@ -18,10 +18,10 @@ function positiveClassesTest(x: A | B) {
}
}
class AOpt { a?: string }
class BOpn { b?: string }
class AWithOptionalProp { a?: string; }
class BWithOptionalProp { b?: string; }
function positiveTestClassesWithOptionalProperties(x: AOpt | BOpn) {
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
if ("a" in x) {
x.a = "1";
} else {
@ -30,11 +30,11 @@ function positiveTestClassesWithOptionalProperties(x: AOpt | BOpn) {
}
class AWithMethod {
a(): string { return "" }
a(): string { return ""; }
}
class BWithMethod {
b(): string { return "" }
b(): string { return ""; }
}
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
@ -55,8 +55,8 @@ function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWit
}
}
class C { a: string }
class D { a: string }
class C { a: string; }
class D { a: string; }
function negativeMultipleClassesTest(x: A | B | C | D) {
if ("a" in x) {
@ -66,9 +66,9 @@ function negativeMultipleClassesTest(x: A | B | C | D) {
}
}
class ClassWithProp { prop: A | B }
class ClassWithUnionProp { prop: A | B }
function negativePropTest(x: ClassWithProp) {
function negativePropTest(x: ClassWithUnionProp) {
if ("a" in x.prop) {
let y: string = x.prop.b;
} else {
@ -79,7 +79,7 @@ function negativePropTest(x: ClassWithProp) {
class NegativeClassTest {
protected prop: A | B;
inThis() {
if ('a' in this.prop) {
if ("a" in this.prop) {
let z: number = this.prop.b;
} else {
let y: string = this.prop.a;
@ -90,7 +90,7 @@ class NegativeClassTest {
class UnreachableCodeDetection {
a: string;
inThis() {
if ('a' in this) {
if ("a" in this) {
} else {
let y = this.a;
}
@ -124,15 +124,15 @@ function positiveClassesTest(x) {
x.a = "1";
}
}
var AOpt = (function () {
function AOpt() {
var AWithOptionalProp = (function () {
function AWithOptionalProp() {
}
return AOpt;
return AWithOptionalProp;
}());
var BOpn = (function () {
function BOpn() {
var BWithOptionalProp = (function () {
function BWithOptionalProp() {
}
return BOpn;
return BWithOptionalProp;
}());
function positiveTestClassesWithOptionalProperties(x) {
if ("a" in x) {
@ -190,10 +190,10 @@ function negativeMultipleClassesTest(x) {
x.a = "1";
}
}
var ClassWithProp = (function () {
function ClassWithProp() {
var ClassWithUnionProp = (function () {
function ClassWithUnionProp() {
}
return ClassWithProp;
return ClassWithUnionProp;
}());
function negativePropTest(x) {
if ("a" in x.prop) {
@ -207,7 +207,7 @@ var NegativeClassTest = (function () {
function NegativeClassTest() {
}
NegativeClassTest.prototype.inThis = function () {
if ('a' in this.prop) {
if ("a" in this.prop) {
var z = this.prop.b;
}
else {
@ -220,7 +220,7 @@ var UnreachableCodeDetection = (function () {
function UnreachableCodeDetection() {
}
UnreachableCodeDetection.prototype.inThis = function () {
if ('a' in this) {
if ("a" in this) {
}
else {
var y = this.a;

View file

@ -3,8 +3,6 @@ class A { a: string; }
class B { b: number; }
class C { b: Object; }
class D { a: Date; }
class ClassWithProp { prop: A | B }
class NestedClassWithProp { outer: ClassWithProp }
function namedClasses(x: A | B) {
if ("a" in x) {
@ -29,6 +27,20 @@ function anonymousClasses(x: { a: string; } | { b: number; }) {
let z: number = x.b;
}
}
class AWithOptionalProp { a?: string; }
class BWithOptionalProp { b?: string; }
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
if ("a" in x) {
x.a = "1";
} else {
const y: string = x instanceof AWithOptionalProp
? x.a
: x.b
}
}
function inParenthesizedExpression(x: A | B) {
if ("a" in (x)) {
let y: string = x.a;
@ -37,8 +49,9 @@ function inParenthesizedExpression(x: A | B) {
}
}
class ClassWithUnionProp { prop: A | B; }
function inProperty(x: ClassWithProp) {
function inProperty(x: ClassWithUnionProp) {
if ("a" in x.prop) {
let y: string = x.prop.a;
} else {
@ -46,6 +59,7 @@ function inProperty(x: ClassWithProp) {
}
}
class NestedClassWithProp { outer: ClassWithUnionProp; }
function innestedProperty(x: NestedClassWithProp) {
if ("a" in x.outer.prop) {
@ -58,7 +72,7 @@ function innestedProperty(x: NestedClassWithProp) {
class InMemberOfClass {
protected prop: A | B;
inThis() {
if ('a' in this.prop) {
if ("a" in this.prop) {
let y: string = this.prop.a;
} else {
let z: number = this.prop.b;
@ -66,11 +80,11 @@ class InMemberOfClass {
}
}
//added for completeness
// added for completeness
class SelfAssert {
a: string;
inThis() {
if ('a' in this) {
if ("a" in this) {
let y: string = this.a;
} else {
}
@ -98,16 +112,6 @@ var D = (function () {
}
return D;
}());
var ClassWithProp = (function () {
function ClassWithProp() {
}
return ClassWithProp;
}());
var NestedClassWithProp = (function () {
function NestedClassWithProp() {
}
return NestedClassWithProp;
}());
function namedClasses(x) {
if ("a" in x) {
x.a = "1";
@ -132,6 +136,26 @@ function anonymousClasses(x) {
var z = x.b;
}
}
var AWithOptionalProp = (function () {
function AWithOptionalProp() {
}
return AWithOptionalProp;
}());
var BWithOptionalProp = (function () {
function BWithOptionalProp() {
}
return BWithOptionalProp;
}());
function positiveTestClassesWithOptionalProperties(x) {
if ("a" in x) {
x.a = "1";
}
else {
var y = x instanceof AWithOptionalProp
? x.a
: x.b;
}
}
function inParenthesizedExpression(x) {
if ("a" in (x)) {
var y = x.a;
@ -140,6 +164,11 @@ function inParenthesizedExpression(x) {
var z = x.b;
}
}
var ClassWithUnionProp = (function () {
function ClassWithUnionProp() {
}
return ClassWithUnionProp;
}());
function inProperty(x) {
if ("a" in x.prop) {
var y = x.prop.a;
@ -148,6 +177,11 @@ function inProperty(x) {
var z = x.prop.b;
}
}
var NestedClassWithProp = (function () {
function NestedClassWithProp() {
}
return NestedClassWithProp;
}());
function innestedProperty(x) {
if ("a" in x.outer.prop) {
var y = x.outer.prop.a;
@ -160,7 +194,7 @@ var InMemberOfClass = (function () {
function InMemberOfClass() {
}
InMemberOfClass.prototype.inThis = function () {
if ('a' in this.prop) {
if ("a" in this.prop) {
var y = this.prop.a;
}
else {
@ -169,12 +203,12 @@ var InMemberOfClass = (function () {
};
return InMemberOfClass;
}());
//added for completeness
// added for completeness
var SelfAssert = (function () {
function SelfAssert() {
}
SelfAssert.prototype.inThis = function () {
if ('a' in this) {
if ("a" in this) {
var y = this.a;
}
else {

View file

@ -17,234 +17,273 @@ class D { a: Date; }
>a : Symbol(D.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 9))
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
class ClassWithProp { prop: A | B }
>ClassWithProp : Symbol(ClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 20))
>prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
class NestedClassWithProp { outer: ClassWithProp }
>NestedClassWithProp : Symbol(NestedClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 35))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 27))
>ClassWithProp : Symbol(ClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 20))
function namedClasses(x: A | B) {
>namedClasses : Symbol(namedClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 50))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 7, 22))
>namedClasses : Symbol(namedClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 20))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
if ("a" in x) {
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 7, 22))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
x.a = "1";
>x.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 7, 22))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
} else {
x.b = 1;
>x.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 7, 22))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
}
}
function multipleClasses(x: A | B | C | D) {
>multipleClasses : Symbol(multipleClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 15, 25))
>multipleClasses : Symbol(multipleClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 11, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
>C : Symbol(C, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 22))
>D : Symbol(D, Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 22))
if ("a" in x) {
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 15, 25))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
let y: string | Date = x.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 17, 11))
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 15, 11))
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>x.a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 15, 25))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 9))
} else {
let z: number | Object = x.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 19, 11))
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 17, 11))
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>x.b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 15, 25))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 9))
}
}
function anonymousClasses(x: { a: string; } | { b: number; }) {
>anonymousClasses : Symbol(anonymousClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 26))
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 30))
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 47))
>anonymousClasses : Symbol(anonymousClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 19, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 30))
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 47))
if ("a" in x) {
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 26))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
let y: string = x.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 25, 11))
>x.a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 30))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 26))
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 30))
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 11))
>x.a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 30))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 30))
} else {
let z: number = x.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 27, 11))
>x.b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 47))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 26))
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 47))
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 25, 11))
>x.b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 47))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 47))
}
}
class AWithOptionalProp { a?: string; }
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 27, 1))
>a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
class BWithOptionalProp { b?: string; }
>BWithOptionalProp : Symbol(BWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 39))
>b : Symbol(BWithOptionalProp.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 25))
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
>positiveTestClassesWithOptionalProperties : Symbol(positiveTestClassesWithOptionalProperties, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 39))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 27, 1))
>BWithOptionalProp : Symbol(BWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 39))
if ("a" in x) {
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
x.a = "1";
>x.a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
>a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
} else {
const y: string = x instanceof AWithOptionalProp
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 36, 13))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 27, 1))
? x.a
>x.a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
>a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
: x.b
>x.b : Symbol(BWithOptionalProp.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 25))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
>b : Symbol(BWithOptionalProp.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 25))
}
}
function inParenthesizedExpression(x: A | B) {
>inParenthesizedExpression : Symbol(inParenthesizedExpression, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 35))
>inParenthesizedExpression : Symbol(inParenthesizedExpression, Decl(typeGuardOfFromPropNameInUnionType.ts, 40, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
if ("a" in (x)) {
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 35))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
let y: string = x.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 11))
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 44, 11))
>x.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 35))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
} else {
let z: number = x.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 34, 11))
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 46, 11))
>x.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 35))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
}
}
class ClassWithUnionProp { prop: A | B; }
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 1))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
function inProperty(x: ClassWithProp) {
>inProperty : Symbol(inProperty, Decl(typeGuardOfFromPropNameInUnionType.ts, 36, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 39, 20))
>ClassWithProp : Symbol(ClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 20))
function inProperty(x: ClassWithUnionProp) {
>inProperty : Symbol(inProperty, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 41))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 1))
if ("a" in x.prop) {
>x.prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 39, 20))
>prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
let y: string = x.prop.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 41, 11))
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 54, 11))
>x.prop.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
>x.prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 39, 20))
>prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
} else {
let z: number = x.prop.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 43, 11))
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 56, 11))
>x.prop.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
>x.prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 39, 20))
>prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
}
}
class NestedClassWithProp { outer: ClassWithUnionProp; }
>NestedClassWithProp : Symbol(NestedClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 58, 1))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 1))
function innestedProperty(x: NestedClassWithProp) {
>innestedProperty : Symbol(innestedProperty, Decl(typeGuardOfFromPropNameInUnionType.ts, 45, 1))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 26))
>NestedClassWithProp : Symbol(NestedClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 35))
>innestedProperty : Symbol(innestedProperty, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 56))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
>NestedClassWithProp : Symbol(NestedClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 58, 1))
if ("a" in x.outer.prop) {
>x.outer.prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 27))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 26))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 27))
>prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x.outer.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
let y: string = x.outer.prop.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 11))
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 64, 11))
>x.outer.prop.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
>x.outer.prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 27))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 26))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 27))
>prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x.outer.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
} else {
let z: number = x.outer.prop.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 11))
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 66, 11))
>x.outer.prop.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
>x.outer.prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 27))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 26))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 27))
>prop : Symbol(ClassWithProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 4, 21))
>x.outer.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
}
}
class InMemberOfClass {
>InMemberOfClass : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 54, 1))
>InMemberOfClass : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
protected prop: A | B;
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 56, 23))
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
inThis() {
>inThis : Symbol(InMemberOfClass.inThis, Decl(typeGuardOfFromPropNameInUnionType.ts, 57, 26))
>inThis : Symbol(InMemberOfClass.inThis, Decl(typeGuardOfFromPropNameInUnionType.ts, 71, 26))
if ('a' in this.prop) {
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 56, 23))
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 54, 1))
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 56, 23))
if ("a" in this.prop) {
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
let y: string = this.prop.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 15))
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 74, 15))
>this.prop.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 56, 23))
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 54, 1))
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 56, 23))
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
} else {
let z: number = this.prop.b;
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 15))
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 76, 15))
>this.prop.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 56, 23))
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 54, 1))
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 56, 23))
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
}
}
}
//added for completeness
// added for completeness
class SelfAssert {
>SelfAssert : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 65, 1))
>SelfAssert : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 79, 1))
a: string;
>a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 18))
>a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 82, 18))
inThis() {
>inThis : Symbol(SelfAssert.inThis, Decl(typeGuardOfFromPropNameInUnionType.ts, 69, 14))
>inThis : Symbol(SelfAssert.inThis, Decl(typeGuardOfFromPropNameInUnionType.ts, 83, 14))
if ('a' in this) {
>this : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 65, 1))
if ("a" in this) {
>this : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 79, 1))
let y: string = this.a;
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 72, 15))
>this.a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 18))
>this : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 65, 1))
>a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 18))
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 86, 15))
>this.a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 82, 18))
>this : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 79, 1))
>a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 82, 18))
} else {
}

View file

@ -17,17 +17,6 @@ class D { a: Date; }
>a : Date
>Date : Date
class ClassWithProp { prop: A | B }
>ClassWithProp : ClassWithProp
>prop : A | B
>A : A
>B : B
class NestedClassWithProp { outer: ClassWithProp }
>NestedClassWithProp : NestedClassWithProp
>outer : ClassWithProp
>ClassWithProp : ClassWithProp
function namedClasses(x: A | B) {
>namedClasses : (x: A | B) => void
>x : A | B
@ -111,6 +100,53 @@ function anonymousClasses(x: { a: string; } | { b: number; }) {
>b : number
}
}
class AWithOptionalProp { a?: string; }
>AWithOptionalProp : AWithOptionalProp
>a : string
class BWithOptionalProp { b?: string; }
>BWithOptionalProp : BWithOptionalProp
>b : string
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
>positiveTestClassesWithOptionalProperties : (x: AWithOptionalProp | BWithOptionalProp) => void
>x : AWithOptionalProp | BWithOptionalProp
>AWithOptionalProp : AWithOptionalProp
>BWithOptionalProp : BWithOptionalProp
if ("a" in x) {
>"a" in x : boolean
>"a" : "a"
>x : AWithOptionalProp | BWithOptionalProp
x.a = "1";
>x.a = "1" : "1"
>x.a : string
>x : AWithOptionalProp
>a : string
>"1" : "1"
} else {
const y: string = x instanceof AWithOptionalProp
>y : string
>x instanceof AWithOptionalProp ? x.a : x.b : string
>x instanceof AWithOptionalProp : boolean
>x : AWithOptionalProp | BWithOptionalProp
>AWithOptionalProp : typeof AWithOptionalProp
? x.a
>x.a : string
>x : AWithOptionalProp
>a : string
: x.b
>x.b : string
>x : BWithOptionalProp
>b : string
}
}
function inParenthesizedExpression(x: A | B) {
>inParenthesizedExpression : (x: A | B) => void
>x : A | B
@ -138,24 +174,29 @@ function inParenthesizedExpression(x: A | B) {
}
}
class ClassWithUnionProp { prop: A | B; }
>ClassWithUnionProp : ClassWithUnionProp
>prop : A | B
>A : A
>B : B
function inProperty(x: ClassWithProp) {
>inProperty : (x: ClassWithProp) => void
>x : ClassWithProp
>ClassWithProp : ClassWithProp
function inProperty(x: ClassWithUnionProp) {
>inProperty : (x: ClassWithUnionProp) => void
>x : ClassWithUnionProp
>ClassWithUnionProp : ClassWithUnionProp
if ("a" in x.prop) {
>"a" in x.prop : boolean
>"a" : "a"
>x.prop : A | B
>x : ClassWithProp
>x : ClassWithUnionProp
>prop : A | B
let y: string = x.prop.a;
>y : string
>x.prop.a : string
>x.prop : A
>x : ClassWithProp
>x : ClassWithUnionProp
>prop : A
>a : string
@ -164,12 +205,16 @@ function inProperty(x: ClassWithProp) {
>z : number
>x.prop.b : number
>x.prop : B
>x : ClassWithProp
>x : ClassWithUnionProp
>prop : B
>b : number
}
}
class NestedClassWithProp { outer: ClassWithUnionProp; }
>NestedClassWithProp : NestedClassWithProp
>outer : ClassWithUnionProp
>ClassWithUnionProp : ClassWithUnionProp
function innestedProperty(x: NestedClassWithProp) {
>innestedProperty : (x: NestedClassWithProp) => void
@ -180,18 +225,18 @@ function innestedProperty(x: NestedClassWithProp) {
>"a" in x.outer.prop : boolean
>"a" : "a"
>x.outer.prop : A | B
>x.outer : ClassWithProp
>x.outer : ClassWithUnionProp
>x : NestedClassWithProp
>outer : ClassWithProp
>outer : ClassWithUnionProp
>prop : A | B
let y: string = x.outer.prop.a;
>y : string
>x.outer.prop.a : string
>x.outer.prop : A
>x.outer : ClassWithProp
>x.outer : ClassWithUnionProp
>x : NestedClassWithProp
>outer : ClassWithProp
>outer : ClassWithUnionProp
>prop : A
>a : string
@ -200,9 +245,9 @@ function innestedProperty(x: NestedClassWithProp) {
>z : number
>x.outer.prop.b : number
>x.outer.prop : B
>x.outer : ClassWithProp
>x.outer : ClassWithUnionProp
>x : NestedClassWithProp
>outer : ClassWithProp
>outer : ClassWithUnionProp
>prop : B
>b : number
}
@ -219,9 +264,9 @@ class InMemberOfClass {
inThis() {
>inThis : () => void
if ('a' in this.prop) {
>'a' in this.prop : boolean
>'a' : "a"
if ("a" in this.prop) {
>"a" in this.prop : boolean
>"a" : "a"
>this.prop : A | B
>this : this
>prop : A | B
@ -246,7 +291,7 @@ class InMemberOfClass {
}
}
//added for completeness
// added for completeness
class SelfAssert {
>SelfAssert : SelfAssert
@ -256,9 +301,9 @@ class SelfAssert {
inThis() {
>inThis : () => void
if ('a' in this) {
>'a' in this : boolean
>'a' : "a"
if ("a" in this) {
>"a" in this : boolean
>"a" : "a"
>this : this
let y: string = this.a;

View file

@ -1,97 +1,97 @@
class A { a: string; }
class B { b: string; }
function negativeClassesTest(x: A | B) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
function positiveClassesTest(x: A | B) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
class AOpt { a?: string }
class BOpn { b?: string }
function positiveTestClassesWithOptionalProperties(x: AOpt | BOpn) {
if ("a" in x) {
x.a = "1";
} else {
x.b = "1";
}
}
class AWithMethod {
a(): string { return "" }
}
class BWithMethod {
b(): string { return "" }
}
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
if ("a" in x) {
x.a();
x.b();
} else {
}
}
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
if ("c" in x) {
x.a();
x.b();
} else {
x.a();
x.b();
}
}
class C { a: string }
class D { a: string }
function negativeMultipleClassesTest(x: A | B | C | D) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
class ClassWithProp { prop: A | B }
function negativePropTest(x: ClassWithProp) {
if ("a" in x.prop) {
let y: string = x.prop.b;
} else {
let z: string = x.prop.a;
}
}
class NegativeClassTest {
protected prop: A | B;
inThis() {
if ('a' in this.prop) {
let z: number = this.prop.b;
} else {
let y: string = this.prop.a;
}
}
}
class UnreachableCodeDetection {
a: string;
inThis() {
if ('a' in this) {
} else {
let y = this.a;
}
}
class A { a: string; }
class B { b: string; }
function negativeClassesTest(x: A | B) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
function positiveClassesTest(x: A | B) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
class AWithOptionalProp { a?: string; }
class BWithOptionalProp { b?: string; }
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
if ("a" in x) {
x.a = "1";
} else {
x.b = "1";
}
}
class AWithMethod {
a(): string { return ""; }
}
class BWithMethod {
b(): string { return ""; }
}
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
if ("a" in x) {
x.a();
x.b();
} else {
}
}
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
if ("c" in x) {
x.a();
x.b();
} else {
x.a();
x.b();
}
}
class C { a: string; }
class D { a: string; }
function negativeMultipleClassesTest(x: A | B | C | D) {
if ("a" in x) {
x.b = "1";
} else {
x.a = "1";
}
}
class ClassWithUnionProp { prop: A | B }
function negativePropTest(x: ClassWithUnionProp) {
if ("a" in x.prop) {
let y: string = x.prop.b;
} else {
let z: string = x.prop.a;
}
}
class NegativeClassTest {
protected prop: A | B;
inThis() {
if ("a" in this.prop) {
let z: number = this.prop.b;
} else {
let y: string = this.prop.a;
}
}
}
class UnreachableCodeDetection {
a: string;
inThis() {
if ("a" in this) {
} else {
let y = this.a;
}
}
}

View file

@ -1,77 +1,91 @@
class A { a: string; }
class B { b: number; }
class C { b: Object; }
class D { a: Date; }
class ClassWithProp { prop: A | B }
class NestedClassWithProp { outer: ClassWithProp }
function namedClasses(x: A | B) {
if ("a" in x) {
x.a = "1";
} else {
x.b = 1;
}
}
function multipleClasses(x: A | B | C | D) {
if ("a" in x) {
let y: string | Date = x.a;
} else {
let z: number | Object = x.b;
}
}
function anonymousClasses(x: { a: string; } | { b: number; }) {
if ("a" in x) {
let y: string = x.a;
} else {
let z: number = x.b;
}
}
function inParenthesizedExpression(x: A | B) {
if ("a" in (x)) {
let y: string = x.a;
} else {
let z: number = x.b;
}
}
function inProperty(x: ClassWithProp) {
if ("a" in x.prop) {
let y: string = x.prop.a;
} else {
let z: number = x.prop.b;
}
}
function innestedProperty(x: NestedClassWithProp) {
if ("a" in x.outer.prop) {
let y: string = x.outer.prop.a;
} else {
let z: number = x.outer.prop.b;
}
}
class InMemberOfClass {
protected prop: A | B;
inThis() {
if ('a' in this.prop) {
let y: string = this.prop.a;
} else {
let z: number = this.prop.b;
}
}
}
//added for completeness
class SelfAssert {
a: string;
inThis() {
if ('a' in this) {
let y: string = this.a;
} else {
}
}
class A { a: string; }
class B { b: number; }
class C { b: Object; }
class D { a: Date; }
function namedClasses(x: A | B) {
if ("a" in x) {
x.a = "1";
} else {
x.b = 1;
}
}
function multipleClasses(x: A | B | C | D) {
if ("a" in x) {
let y: string | Date = x.a;
} else {
let z: number | Object = x.b;
}
}
function anonymousClasses(x: { a: string; } | { b: number; }) {
if ("a" in x) {
let y: string = x.a;
} else {
let z: number = x.b;
}
}
class AWithOptionalProp { a?: string; }
class BWithOptionalProp { b?: string; }
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
if ("a" in x) {
x.a = "1";
} else {
const y: string = x instanceof AWithOptionalProp
? x.a
: x.b
}
}
function inParenthesizedExpression(x: A | B) {
if ("a" in (x)) {
let y: string = x.a;
} else {
let z: number = x.b;
}
}
class ClassWithUnionProp { prop: A | B; }
function inProperty(x: ClassWithUnionProp) {
if ("a" in x.prop) {
let y: string = x.prop.a;
} else {
let z: number = x.prop.b;
}
}
class NestedClassWithProp { outer: ClassWithUnionProp; }
function innestedProperty(x: NestedClassWithProp) {
if ("a" in x.outer.prop) {
let y: string = x.outer.prop.a;
} else {
let z: number = x.outer.prop.b;
}
}
class InMemberOfClass {
protected prop: A | B;
inThis() {
if ("a" in this.prop) {
let y: string = this.prop.a;
} else {
let z: number = this.prop.b;
}
}
}
// added for completeness
class SelfAssert {
a: string;
inThis() {
if ("a" in this) {
let y: string = this.a;
} else {
}
}
}