mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Properly handle partial union type properties in isTypePresencePossible (#53794)
This commit is contained in:
parent
378ffa4bc9
commit
e782cef221
@ -27006,7 +27006,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;
|
||||
}
|
||||
|
||||
|
||||
@ -432,4 +432,33 @@ tests/cases/compiler/inKeywordTypeguard.ts(186,21): error TS2322: Type 'T' is no
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
// Repro from #53773
|
||||
|
||||
function test1<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if (Array.isArray(obj) || 'length' in obj) {
|
||||
obj; // T
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
function test2<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if (Array.isArray(obj)) {
|
||||
obj; // T & any[]
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
function test3<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if ('length' in obj) {
|
||||
obj; // T
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,6 +353,35 @@ function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
// Repro from #53773
|
||||
|
||||
function test1<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if (Array.isArray(obj) || 'length' in obj) {
|
||||
obj; // T
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
function test2<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if (Array.isArray(obj)) {
|
||||
obj; // T & any[]
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
function test3<T extends any[] | Record<string, any>>(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
|
||||
}
|
||||
}
|
||||
|
||||
@ -879,3 +879,69 @@ const f = <P extends object>(a: P & {}) => {
|
||||
|
||||
};
|
||||
|
||||
// Repro from #53773
|
||||
|
||||
function test1<T extends any[] | Record<string, any>>(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<T extends any[] | Record<string, any>>(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<T extends any[] | Record<string, any>>(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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1085,3 +1085,67 @@ const f = <P extends object>(a: P & {}) => {
|
||||
|
||||
};
|
||||
|
||||
// Repro from #53773
|
||||
|
||||
function test1<T extends any[] | Record<string, any>>(obj: T) {
|
||||
>test1 : <T extends any[] | Record<string, any>>(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<string, any>
|
||||
>'length' in obj : boolean
|
||||
>'length' : "length"
|
||||
>obj : T
|
||||
|
||||
obj; // T
|
||||
>obj : T
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
>obj : T
|
||||
}
|
||||
}
|
||||
|
||||
function test2<T extends any[] | Record<string, any>>(obj: T) {
|
||||
>test2 : <T extends any[] | Record<string, any>>(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<string, any>
|
||||
|
||||
obj; // T & any[]
|
||||
>obj : T & any[]
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
>obj : T
|
||||
}
|
||||
}
|
||||
|
||||
function test3<T extends any[] | Record<string, any>>(obj: T) {
|
||||
>test3 : <T extends any[] | Record<string, any>>(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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -452,4 +452,33 @@ tests/cases/compiler/inKeywordTypeguard.ts(186,21): error TS2638: Type 'NonNulla
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
// Repro from #53773
|
||||
|
||||
function test1<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if (Array.isArray(obj) || 'length' in obj) {
|
||||
obj; // T
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
function test2<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if (Array.isArray(obj)) {
|
||||
obj; // T & any[]
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
function test3<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if ('length' in obj) {
|
||||
obj; // T
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,6 +353,35 @@ function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
// Repro from #53773
|
||||
|
||||
function test1<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if (Array.isArray(obj) || 'length' in obj) {
|
||||
obj; // T
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
function test2<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if (Array.isArray(obj)) {
|
||||
obj; // T & any[]
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
function test3<T extends any[] | Record<string, any>>(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
|
||||
}
|
||||
}
|
||||
|
||||
@ -879,3 +879,69 @@ const f = <P extends object>(a: P & {}) => {
|
||||
|
||||
};
|
||||
|
||||
// Repro from #53773
|
||||
|
||||
function test1<T extends any[] | Record<string, any>>(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<T extends any[] | Record<string, any>>(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<T extends any[] | Record<string, any>>(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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1085,3 +1085,67 @@ const f = <P extends object>(a: P & {}) => {
|
||||
|
||||
};
|
||||
|
||||
// Repro from #53773
|
||||
|
||||
function test1<T extends any[] | Record<string, any>>(obj: T) {
|
||||
>test1 : <T extends any[] | Record<string, any>>(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<string, any>
|
||||
>'length' in obj : boolean
|
||||
>'length' : "length"
|
||||
>obj : T
|
||||
|
||||
obj; // T
|
||||
>obj : T
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
>obj : T
|
||||
}
|
||||
}
|
||||
|
||||
function test2<T extends any[] | Record<string, any>>(obj: T) {
|
||||
>test2 : <T extends any[] | Record<string, any>>(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<string, any>
|
||||
|
||||
obj; // T & any[]
|
||||
>obj : T & any[]
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
>obj : T
|
||||
}
|
||||
}
|
||||
|
||||
function test3<T extends any[] | Record<string, any>>(obj: T) {
|
||||
>test3 : <T extends any[] | Record<string, any>>(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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -355,3 +355,32 @@ function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
// Repro from #53773
|
||||
|
||||
function test1<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if (Array.isArray(obj) || 'length' in obj) {
|
||||
obj; // T
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
function test2<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if (Array.isArray(obj)) {
|
||||
obj; // T & any[]
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
function test3<T extends any[] | Record<string, any>>(obj: T) {
|
||||
if ('length' in obj) {
|
||||
obj; // T
|
||||
}
|
||||
else {
|
||||
obj; // T
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user