mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-20 10:29:36 -06:00
Fixed an issue with in not being able to be used on narrowed down expression of a generic nullable type (#51502)
* Fixed an issue with `in` not being able to be used on narrowed down expression of a generic nullable type * Add another test case from a new issue * Move the fix to `hasEmptyObjectIntersection`
This commit is contained in:
parent
12d7e4bdbf
commit
5cd2d975c3
@ -34998,7 +34998,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function hasEmptyObjectIntersection(type: Type): boolean {
|
||||
return someType(type, t => t === unknownEmptyObjectType || !!(t.flags & TypeFlags.Intersection) && some((t as IntersectionType).types, isEmptyAnonymousObjectType));
|
||||
return someType(type, t => t === unknownEmptyObjectType || !!(t.flags & TypeFlags.Intersection) && isEmptyAnonymousObjectType(getBaseConstraintOrType(t)));
|
||||
}
|
||||
|
||||
function checkInExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
|
||||
|
||||
@ -420,4 +420,16 @@ tests/cases/compiler/inKeywordTypeguard.ts(186,21): error TS2322: Type 'T' is no
|
||||
|
||||
const checkIsTouchDevice = () =>
|
||||
"ontouchstart" in window || "msMaxTouchPoints" in window.navigator;
|
||||
|
||||
// Repro from #51501
|
||||
|
||||
function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
return !!table && 'html' in table;
|
||||
}
|
||||
|
||||
// Repro from #51549
|
||||
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
@ -341,6 +341,18 @@ function foo<A>(value: A) {
|
||||
|
||||
const checkIsTouchDevice = () =>
|
||||
"ontouchstart" in window || "msMaxTouchPoints" in window.navigator;
|
||||
|
||||
// Repro from #51501
|
||||
|
||||
function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
return !!table && 'html' in table;
|
||||
}
|
||||
|
||||
// Repro from #51549
|
||||
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
|
||||
//// [inKeywordTypeguard.js]
|
||||
@ -655,3 +667,11 @@ function foo(value) {
|
||||
}
|
||||
// Repro from #50954
|
||||
const checkIsTouchDevice = () => "ontouchstart" in window || "msMaxTouchPoints" in window.navigator;
|
||||
// Repro from #51501
|
||||
function isHTMLTable(table) {
|
||||
return !!table && 'html' in table;
|
||||
}
|
||||
// Repro from #51549
|
||||
const f = (a) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
@ -853,3 +853,29 @@ const checkIsTouchDevice = () =>
|
||||
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
|
||||
>navigator : Symbol(navigator, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
// Repro from #51501
|
||||
|
||||
function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
>isHTMLTable : Symbol(isHTMLTable, Decl(inKeywordTypeguard.ts, 341, 71))
|
||||
>T : Symbol(T, Decl(inKeywordTypeguard.ts, 345, 21))
|
||||
>table : Symbol(table, Decl(inKeywordTypeguard.ts, 345, 46))
|
||||
>T : Symbol(T, Decl(inKeywordTypeguard.ts, 345, 21))
|
||||
|
||||
return !!table && 'html' in table;
|
||||
>table : Symbol(table, Decl(inKeywordTypeguard.ts, 345, 46))
|
||||
>table : Symbol(table, Decl(inKeywordTypeguard.ts, 345, 46))
|
||||
}
|
||||
|
||||
// Repro from #51549
|
||||
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
>f : Symbol(f, Decl(inKeywordTypeguard.ts, 351, 5))
|
||||
>P : Symbol(P, Decl(inKeywordTypeguard.ts, 351, 11))
|
||||
>a : Symbol(a, Decl(inKeywordTypeguard.ts, 351, 29))
|
||||
>P : Symbol(P, Decl(inKeywordTypeguard.ts, 351, 11))
|
||||
|
||||
"foo" in a;
|
||||
>a : Symbol(a, Decl(inKeywordTypeguard.ts, 351, 29))
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1056,3 +1056,34 @@ const checkIsTouchDevice = () =>
|
||||
>window : Window & typeof globalThis
|
||||
>navigator : Navigator
|
||||
|
||||
// Repro from #51501
|
||||
|
||||
function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
>isHTMLTable : <T extends object>(table: T) => boolean
|
||||
>null : null
|
||||
>table : T
|
||||
|
||||
return !!table && 'html' in table;
|
||||
>!!table && 'html' in table : boolean
|
||||
>!!table : boolean
|
||||
>!table : boolean
|
||||
>table : T
|
||||
>'html' in table : boolean
|
||||
>'html' : "html"
|
||||
>table : T
|
||||
}
|
||||
|
||||
// Repro from #51549
|
||||
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
>f : <P extends object>(a: P & {}) => void
|
||||
><P extends object>(a: P & {}) => { "foo" in a;} : <P extends object>(a: P & {}) => void
|
||||
>a : P & {}
|
||||
|
||||
"foo" in a;
|
||||
>"foo" in a : boolean
|
||||
>"foo" : "foo"
|
||||
>a : P & {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -440,4 +440,16 @@ tests/cases/compiler/inKeywordTypeguard.ts(186,21): error TS2638: Type 'NonNulla
|
||||
|
||||
const checkIsTouchDevice = () =>
|
||||
"ontouchstart" in window || "msMaxTouchPoints" in window.navigator;
|
||||
|
||||
// Repro from #51501
|
||||
|
||||
function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
return !!table && 'html' in table;
|
||||
}
|
||||
|
||||
// Repro from #51549
|
||||
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
@ -341,6 +341,18 @@ function foo<A>(value: A) {
|
||||
|
||||
const checkIsTouchDevice = () =>
|
||||
"ontouchstart" in window || "msMaxTouchPoints" in window.navigator;
|
||||
|
||||
// Repro from #51501
|
||||
|
||||
function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
return !!table && 'html' in table;
|
||||
}
|
||||
|
||||
// Repro from #51549
|
||||
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
|
||||
//// [inKeywordTypeguard.js]
|
||||
@ -656,3 +668,11 @@ function foo(value) {
|
||||
}
|
||||
// Repro from #50954
|
||||
const checkIsTouchDevice = () => "ontouchstart" in window || "msMaxTouchPoints" in window.navigator;
|
||||
// Repro from #51501
|
||||
function isHTMLTable(table) {
|
||||
return !!table && 'html' in table;
|
||||
}
|
||||
// Repro from #51549
|
||||
const f = (a) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
@ -853,3 +853,29 @@ const checkIsTouchDevice = () =>
|
||||
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
|
||||
>navigator : Symbol(navigator, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
// Repro from #51501
|
||||
|
||||
function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
>isHTMLTable : Symbol(isHTMLTable, Decl(inKeywordTypeguard.ts, 341, 71))
|
||||
>T : Symbol(T, Decl(inKeywordTypeguard.ts, 345, 21))
|
||||
>table : Symbol(table, Decl(inKeywordTypeguard.ts, 345, 46))
|
||||
>T : Symbol(T, Decl(inKeywordTypeguard.ts, 345, 21))
|
||||
|
||||
return !!table && 'html' in table;
|
||||
>table : Symbol(table, Decl(inKeywordTypeguard.ts, 345, 46))
|
||||
>table : Symbol(table, Decl(inKeywordTypeguard.ts, 345, 46))
|
||||
}
|
||||
|
||||
// Repro from #51549
|
||||
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
>f : Symbol(f, Decl(inKeywordTypeguard.ts, 351, 5))
|
||||
>P : Symbol(P, Decl(inKeywordTypeguard.ts, 351, 11))
|
||||
>a : Symbol(a, Decl(inKeywordTypeguard.ts, 351, 29))
|
||||
>P : Symbol(P, Decl(inKeywordTypeguard.ts, 351, 11))
|
||||
|
||||
"foo" in a;
|
||||
>a : Symbol(a, Decl(inKeywordTypeguard.ts, 351, 29))
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1056,3 +1056,34 @@ const checkIsTouchDevice = () =>
|
||||
>window : Window & typeof globalThis
|
||||
>navigator : Navigator
|
||||
|
||||
// Repro from #51501
|
||||
|
||||
function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
>isHTMLTable : <T extends object | null>(table: T) => boolean
|
||||
>null : null
|
||||
>table : T
|
||||
|
||||
return !!table && 'html' in table;
|
||||
>!!table && 'html' in table : boolean
|
||||
>!!table : boolean
|
||||
>!table : boolean
|
||||
>table : T
|
||||
>'html' in table : boolean
|
||||
>'html' : "html"
|
||||
>table : NonNullable<T>
|
||||
}
|
||||
|
||||
// Repro from #51549
|
||||
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
>f : <P extends object>(a: P & {}) => void
|
||||
><P extends object>(a: P & {}) => { "foo" in a;} : <P extends object>(a: P & {}) => void
|
||||
>a : P & {}
|
||||
|
||||
"foo" in a;
|
||||
>"foo" in a : boolean
|
||||
>"foo" : "foo"
|
||||
>a : P & {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -343,3 +343,15 @@ function foo<A>(value: A) {
|
||||
|
||||
const checkIsTouchDevice = () =>
|
||||
"ontouchstart" in window || "msMaxTouchPoints" in window.navigator;
|
||||
|
||||
// Repro from #51501
|
||||
|
||||
function isHTMLTable<T extends object | null>(table: T): boolean {
|
||||
return !!table && 'html' in table;
|
||||
}
|
||||
|
||||
// Repro from #51549
|
||||
|
||||
const f = <P extends object>(a: P & {}) => {
|
||||
"foo" in a;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user