diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 5e9c72ec48319..3c48f03df8861 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -27001,7 +27001,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function isTypePresencePossible(type: Type, propName: __String, assumeTrue: boolean) {
const prop = getPropertyOfType(type, propName);
return prop ?
- !!(prop.flags & SymbolFlags.Optional) || assumeTrue :
+ !!(prop.flags & SymbolFlags.Optional || getCheckFlags(prop) & CheckFlags.Partial) || assumeTrue :
!!getApplicableIndexInfoForName(type, propName) || !assumeTrue;
}
diff --git a/tests/baselines/reference/inKeywordTypeguard(strict=false).errors.txt b/tests/baselines/reference/inKeywordTypeguard(strict=false).errors.txt
index 7d8bd0bea9a4b..dd3d705b7fdb6 100644
--- a/tests/baselines/reference/inKeywordTypeguard(strict=false).errors.txt
+++ b/tests/baselines/reference/inKeywordTypeguard(strict=false).errors.txt
@@ -432,4 +432,33 @@ tests/cases/compiler/inKeywordTypeguard.ts(186,21): error TS2322: Type 'T' is no
const f =
(a: P & {}) => {
"foo" in a;
};
+
+ // Repro from #53773
+
+ function test1>(obj: T) {
+ if (Array.isArray(obj) || 'length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+ }
+
+ function test2>(obj: T) {
+ if (Array.isArray(obj)) {
+ obj; // T & any[]
+ }
+ else {
+ obj; // T
+ }
+ }
+
+ function test3>(obj: T) {
+ if ('length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+ }
\ No newline at end of file
diff --git a/tests/baselines/reference/inKeywordTypeguard(strict=false).js b/tests/baselines/reference/inKeywordTypeguard(strict=false).js
index ae1ccbb43c5be..d42e84293a198 100644
--- a/tests/baselines/reference/inKeywordTypeguard(strict=false).js
+++ b/tests/baselines/reference/inKeywordTypeguard(strict=false).js
@@ -353,6 +353,35 @@ function isHTMLTable(table: T): boolean {
const f = (a: P & {}) => {
"foo" in a;
};
+
+// Repro from #53773
+
+function test1>(obj: T) {
+ if (Array.isArray(obj) || 'length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+}
+
+function test2>(obj: T) {
+ if (Array.isArray(obj)) {
+ obj; // T & any[]
+ }
+ else {
+ obj; // T
+ }
+}
+
+function test3>(obj: T) {
+ if ('length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+}
//// [inKeywordTypeguard.js]
@@ -675,3 +704,28 @@ function isHTMLTable(table) {
const f = (a) => {
"foo" in a;
};
+// Repro from #53773
+function test1(obj) {
+ if (Array.isArray(obj) || 'length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+}
+function test2(obj) {
+ if (Array.isArray(obj)) {
+ obj; // T & any[]
+ }
+ else {
+ obj; // T
+ }
+}
+function test3(obj) {
+ if ('length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+}
diff --git a/tests/baselines/reference/inKeywordTypeguard(strict=false).symbols b/tests/baselines/reference/inKeywordTypeguard(strict=false).symbols
index 9444bf3fc988c..3cbb8f33cc072 100644
--- a/tests/baselines/reference/inKeywordTypeguard(strict=false).symbols
+++ b/tests/baselines/reference/inKeywordTypeguard(strict=false).symbols
@@ -879,3 +879,69 @@ const f = (a: P & {}) => {
};
+// Repro from #53773
+
+function test1>(obj: T) {
+>test1 : Symbol(test1, Decl(inKeywordTypeguard.ts, 353, 2))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 357, 15))
+>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 357, 54))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 357, 15))
+
+ if (Array.isArray(obj) || 'length' in obj) {
+>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
+>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
+>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 357, 54))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 357, 54))
+
+ obj; // T
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 357, 54))
+ }
+ else {
+ obj; // T
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 357, 54))
+ }
+}
+
+function test2>(obj: T) {
+>test2 : Symbol(test2, Decl(inKeywordTypeguard.ts, 364, 1))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 366, 15))
+>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 366, 54))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 366, 15))
+
+ if (Array.isArray(obj)) {
+>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
+>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
+>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 366, 54))
+
+ obj; // T & any[]
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 366, 54))
+ }
+ else {
+ obj; // T
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 366, 54))
+ }
+}
+
+function test3>(obj: T) {
+>test3 : Symbol(test3, Decl(inKeywordTypeguard.ts, 373, 1))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 375, 15))
+>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 375, 54))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 375, 15))
+
+ if ('length' in obj) {
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 375, 54))
+
+ obj; // T
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 375, 54))
+ }
+ else {
+ obj; // T
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 375, 54))
+ }
+}
+
diff --git a/tests/baselines/reference/inKeywordTypeguard(strict=false).types b/tests/baselines/reference/inKeywordTypeguard(strict=false).types
index 2135c94979733..4f69cf393b59c 100644
--- a/tests/baselines/reference/inKeywordTypeguard(strict=false).types
+++ b/tests/baselines/reference/inKeywordTypeguard(strict=false).types
@@ -1085,3 +1085,67 @@ const f = (a: P & {}) => {
};
+// Repro from #53773
+
+function test1>(obj: T) {
+>test1 : >(obj: T) => void
+>obj : T
+
+ if (Array.isArray(obj) || 'length' in obj) {
+>Array.isArray(obj) || 'length' in obj : boolean
+>Array.isArray(obj) : boolean
+>Array.isArray : (arg: any) => arg is any[]
+>Array : ArrayConstructor
+>isArray : (arg: any) => arg is any[]
+>obj : any[] | Record
+>'length' in obj : boolean
+>'length' : "length"
+>obj : T
+
+ obj; // T
+>obj : T
+ }
+ else {
+ obj; // T
+>obj : T
+ }
+}
+
+function test2>(obj: T) {
+>test2 : >(obj: T) => void
+>obj : T
+
+ if (Array.isArray(obj)) {
+>Array.isArray(obj) : boolean
+>Array.isArray : (arg: any) => arg is any[]
+>Array : ArrayConstructor
+>isArray : (arg: any) => arg is any[]
+>obj : any[] | Record
+
+ obj; // T & any[]
+>obj : T & any[]
+ }
+ else {
+ obj; // T
+>obj : T
+ }
+}
+
+function test3>(obj: T) {
+>test3 : >(obj: T) => void
+>obj : T
+
+ if ('length' in obj) {
+>'length' in obj : boolean
+>'length' : "length"
+>obj : T
+
+ obj; // T
+>obj : T
+ }
+ else {
+ obj; // T
+>obj : T
+ }
+}
+
diff --git a/tests/baselines/reference/inKeywordTypeguard(strict=true).errors.txt b/tests/baselines/reference/inKeywordTypeguard(strict=true).errors.txt
index d47a0718aac8a..f0c97560e5c0b 100644
--- a/tests/baselines/reference/inKeywordTypeguard(strict=true).errors.txt
+++ b/tests/baselines/reference/inKeywordTypeguard(strict=true).errors.txt
@@ -452,4 +452,33 @@ tests/cases/compiler/inKeywordTypeguard.ts(186,21): error TS2638: Type 'NonNulla
const f = (a: P & {}) => {
"foo" in a;
};
+
+ // Repro from #53773
+
+ function test1>(obj: T) {
+ if (Array.isArray(obj) || 'length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+ }
+
+ function test2>(obj: T) {
+ if (Array.isArray(obj)) {
+ obj; // T & any[]
+ }
+ else {
+ obj; // T
+ }
+ }
+
+ function test3>(obj: T) {
+ if ('length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+ }
\ No newline at end of file
diff --git a/tests/baselines/reference/inKeywordTypeguard(strict=true).js b/tests/baselines/reference/inKeywordTypeguard(strict=true).js
index 73b2cf77cae44..01bd93fe8526e 100644
--- a/tests/baselines/reference/inKeywordTypeguard(strict=true).js
+++ b/tests/baselines/reference/inKeywordTypeguard(strict=true).js
@@ -353,6 +353,35 @@ function isHTMLTable(table: T): boolean {
const f = (a: P & {}) => {
"foo" in a;
};
+
+// Repro from #53773
+
+function test1>(obj: T) {
+ if (Array.isArray(obj) || 'length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+}
+
+function test2>(obj: T) {
+ if (Array.isArray(obj)) {
+ obj; // T & any[]
+ }
+ else {
+ obj; // T
+ }
+}
+
+function test3>(obj: T) {
+ if ('length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+}
//// [inKeywordTypeguard.js]
@@ -676,3 +705,28 @@ function isHTMLTable(table) {
const f = (a) => {
"foo" in a;
};
+// Repro from #53773
+function test1(obj) {
+ if (Array.isArray(obj) || 'length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+}
+function test2(obj) {
+ if (Array.isArray(obj)) {
+ obj; // T & any[]
+ }
+ else {
+ obj; // T
+ }
+}
+function test3(obj) {
+ if ('length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+}
diff --git a/tests/baselines/reference/inKeywordTypeguard(strict=true).symbols b/tests/baselines/reference/inKeywordTypeguard(strict=true).symbols
index 9444bf3fc988c..3cbb8f33cc072 100644
--- a/tests/baselines/reference/inKeywordTypeguard(strict=true).symbols
+++ b/tests/baselines/reference/inKeywordTypeguard(strict=true).symbols
@@ -879,3 +879,69 @@ const f = (a: P & {}) => {
};
+// Repro from #53773
+
+function test1>(obj: T) {
+>test1 : Symbol(test1, Decl(inKeywordTypeguard.ts, 353, 2))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 357, 15))
+>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 357, 54))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 357, 15))
+
+ if (Array.isArray(obj) || 'length' in obj) {
+>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
+>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
+>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 357, 54))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 357, 54))
+
+ obj; // T
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 357, 54))
+ }
+ else {
+ obj; // T
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 357, 54))
+ }
+}
+
+function test2>(obj: T) {
+>test2 : Symbol(test2, Decl(inKeywordTypeguard.ts, 364, 1))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 366, 15))
+>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 366, 54))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 366, 15))
+
+ if (Array.isArray(obj)) {
+>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
+>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
+>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 366, 54))
+
+ obj; // T & any[]
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 366, 54))
+ }
+ else {
+ obj; // T
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 366, 54))
+ }
+}
+
+function test3>(obj: T) {
+>test3 : Symbol(test3, Decl(inKeywordTypeguard.ts, 373, 1))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 375, 15))
+>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 375, 54))
+>T : Symbol(T, Decl(inKeywordTypeguard.ts, 375, 15))
+
+ if ('length' in obj) {
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 375, 54))
+
+ obj; // T
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 375, 54))
+ }
+ else {
+ obj; // T
+>obj : Symbol(obj, Decl(inKeywordTypeguard.ts, 375, 54))
+ }
+}
+
diff --git a/tests/baselines/reference/inKeywordTypeguard(strict=true).types b/tests/baselines/reference/inKeywordTypeguard(strict=true).types
index 830b053aab180..d2bb573370368 100644
--- a/tests/baselines/reference/inKeywordTypeguard(strict=true).types
+++ b/tests/baselines/reference/inKeywordTypeguard(strict=true).types
@@ -1085,3 +1085,67 @@ const f = (a: P & {}) => {
};
+// Repro from #53773
+
+function test1>(obj: T) {
+>test1 : >(obj: T) => void
+>obj : T
+
+ if (Array.isArray(obj) || 'length' in obj) {
+>Array.isArray(obj) || 'length' in obj : boolean
+>Array.isArray(obj) : boolean
+>Array.isArray : (arg: any) => arg is any[]
+>Array : ArrayConstructor
+>isArray : (arg: any) => arg is any[]
+>obj : any[] | Record
+>'length' in obj : boolean
+>'length' : "length"
+>obj : T
+
+ obj; // T
+>obj : T
+ }
+ else {
+ obj; // T
+>obj : T
+ }
+}
+
+function test2>(obj: T) {
+>test2 : >(obj: T) => void
+>obj : T
+
+ if (Array.isArray(obj)) {
+>Array.isArray(obj) : boolean
+>Array.isArray : (arg: any) => arg is any[]
+>Array : ArrayConstructor
+>isArray : (arg: any) => arg is any[]
+>obj : any[] | Record
+
+ obj; // T & any[]
+>obj : T & any[]
+ }
+ else {
+ obj; // T
+>obj : T
+ }
+}
+
+function test3>(obj: T) {
+>test3 : >(obj: T) => void
+>obj : T
+
+ if ('length' in obj) {
+>'length' in obj : boolean
+>'length' : "length"
+>obj : T
+
+ obj; // T
+>obj : T
+ }
+ else {
+ obj; // T
+>obj : T
+ }
+}
+
diff --git a/tests/cases/compiler/inKeywordTypeguard.ts b/tests/cases/compiler/inKeywordTypeguard.ts
index 0c74dcded90ba..26145d0c7d9c3 100644
--- a/tests/cases/compiler/inKeywordTypeguard.ts
+++ b/tests/cases/compiler/inKeywordTypeguard.ts
@@ -355,3 +355,32 @@ function isHTMLTable(table: T): boolean {
const f = (a: P & {}) => {
"foo" in a;
};
+
+// Repro from #53773
+
+function test1>(obj: T) {
+ if (Array.isArray(obj) || 'length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+}
+
+function test2>(obj: T) {
+ if (Array.isArray(obj)) {
+ obj; // T & any[]
+ }
+ else {
+ obj; // T
+ }
+}
+
+function test3>(obj: T) {
+ if ('length' in obj) {
+ obj; // T
+ }
+ else {
+ obj; // T
+ }
+}