mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
* Fix #38608 * Work for narrowed non-unions * Add comment
This commit is contained in:
parent
79d3058b83
commit
3d6650eb4f
@ -22963,7 +22963,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
|
||||
if (type.flags & (TypeFlags.Union | TypeFlags.Object)
|
||||
if (type.flags & TypeFlags.Union
|
||||
|| type.flags & TypeFlags.Object && declaredType !== type
|
||||
|| isThisTypeParameter(type)
|
||||
|| type.flags & TypeFlags.Intersection && every((type as IntersectionType).types, t => t.symbol !== globalThisSymbol)) {
|
||||
const propName = escapeLeadingUnderscores(literal.text);
|
||||
|
||||
@ -3,7 +3,6 @@ tests/cases/conformance/fixSignatureCaching.ts(284,10): error TS2339: Property '
|
||||
tests/cases/conformance/fixSignatureCaching.ts(293,10): error TS2339: Property 'FALLBACK_PHONE' does not exist on type '{}'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(294,10): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(295,10): error TS2339: Property 'FALLBACK_MOBILE' does not exist on type '{}'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(301,17): error TS2339: Property 'isArray' does not exist on type 'never'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(330,74): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(369,10): error TS2339: Property 'findMatch' does not exist on type '{}'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(387,10): error TS2339: Property 'findMatches' does not exist on type '{}'.
|
||||
@ -59,7 +58,7 @@ tests/cases/conformance/fixSignatureCaching.ts(981,16): error TS2304: Cannot fin
|
||||
tests/cases/conformance/fixSignatureCaching.ts(983,44): error TS2339: Property 'MobileDetect' does not exist on type 'Window & typeof globalThis'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/fixSignatureCaching.ts (59 errors) ====
|
||||
==== tests/cases/conformance/fixSignatureCaching.ts (58 errors) ====
|
||||
// Repro from #10697
|
||||
|
||||
(function (define, undefined) {
|
||||
@ -371,8 +370,6 @@ tests/cases/conformance/fixSignatureCaching.ts(983,44): error TS2339: Property '
|
||||
isArray = 'isArray' in Array
|
||||
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
|
||||
: Array.isArray;
|
||||
~~~~~~~
|
||||
!!! error TS2339: Property 'isArray' does not exist on type 'never'.
|
||||
|
||||
function equalIC(a, b) {
|
||||
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
|
||||
|
||||
@ -825,7 +825,9 @@ define(function () {
|
||||
>value : Symbol(value, Decl(fixSignatureCaching.ts, 299, 20))
|
||||
|
||||
: Array.isArray;
|
||||
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
function equalIC(a, b) {
|
||||
>equalIC : Symbol(equalIC, Decl(fixSignatureCaching.ts, 300, 24))
|
||||
|
||||
@ -1127,9 +1127,9 @@ define(function () {
|
||||
>'[object Array]' : "[object Array]"
|
||||
|
||||
isArray = 'isArray' in Array
|
||||
>isArray = 'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : any
|
||||
>isArray = 'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : (value: any) => boolean
|
||||
>isArray : any
|
||||
>'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : any
|
||||
>'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : (value: any) => boolean
|
||||
>'isArray' in Array : boolean
|
||||
>'isArray' : "isArray"
|
||||
>Array : ArrayConstructor
|
||||
@ -1150,9 +1150,9 @@ define(function () {
|
||||
>'[object Array]' : "[object Array]"
|
||||
|
||||
: Array.isArray;
|
||||
>Array.isArray : any
|
||||
>Array : never
|
||||
>isArray : any
|
||||
>Array.isArray : <T>(arg: {} | T) => arg is T extends readonly any[] ? unknown extends T ? never : readonly any[] : any[]
|
||||
>Array : ArrayConstructor
|
||||
>isArray : <T>(arg: {} | T) => arg is T extends readonly any[] ? unknown extends T ? never : readonly any[] : any[]
|
||||
|
||||
function equalIC(a, b) {
|
||||
>equalIC : (a: any, b: any) => boolean
|
||||
|
||||
@ -165,6 +165,46 @@ tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' do
|
||||
let n: never = x;
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #38608
|
||||
declare const error: Error;
|
||||
if ('extra' in error) {
|
||||
error // Still Error
|
||||
} else {
|
||||
error // Error
|
||||
}
|
||||
|
||||
function narrowsToNever(x: { l: number } | { r: number }) {
|
||||
let v: number;
|
||||
if ("l" in x) {
|
||||
v = x.l;
|
||||
}
|
||||
else if ("r" in x) {
|
||||
v = x.r;
|
||||
}
|
||||
else {
|
||||
v = x
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
type AOrB = { aProp: number } | { bProp: number };
|
||||
declare function isAOrB(x: unknown): x is AOrB;
|
||||
|
||||
declare var x: unknown;
|
||||
if (isAOrB(x)) {
|
||||
if ("aProp" in x) {
|
||||
x.aProp;
|
||||
}
|
||||
else if ("bProp" in x) {
|
||||
x.bProp;
|
||||
}
|
||||
// x is never because of the type predicate from unknown
|
||||
else if ("cProp" in x) {
|
||||
const _never: never = x;
|
||||
}
|
||||
}
|
||||
|
||||
function negativeIntersectionTest() {
|
||||
if ("ontouchstart" in window) {
|
||||
window.ontouchstart
|
||||
|
||||
@ -104,6 +104,46 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) {
|
||||
let n: never = x;
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #38608
|
||||
declare const error: Error;
|
||||
if ('extra' in error) {
|
||||
error // Still Error
|
||||
} else {
|
||||
error // Error
|
||||
}
|
||||
|
||||
function narrowsToNever(x: { l: number } | { r: number }) {
|
||||
let v: number;
|
||||
if ("l" in x) {
|
||||
v = x.l;
|
||||
}
|
||||
else if ("r" in x) {
|
||||
v = x.r;
|
||||
}
|
||||
else {
|
||||
v = x
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
type AOrB = { aProp: number } | { bProp: number };
|
||||
declare function isAOrB(x: unknown): x is AOrB;
|
||||
|
||||
declare var x: unknown;
|
||||
if (isAOrB(x)) {
|
||||
if ("aProp" in x) {
|
||||
x.aProp;
|
||||
}
|
||||
else if ("bProp" in x) {
|
||||
x.bProp;
|
||||
}
|
||||
// x is never because of the type predicate from unknown
|
||||
else if ("cProp" in x) {
|
||||
const _never: never = x;
|
||||
}
|
||||
}
|
||||
|
||||
function negativeIntersectionTest() {
|
||||
if ("ontouchstart" in window) {
|
||||
window.ontouchstart
|
||||
@ -252,6 +292,37 @@ function positiveIntersectionTest(x) {
|
||||
var n = x;
|
||||
}
|
||||
}
|
||||
if ('extra' in error) {
|
||||
error; // Still Error
|
||||
}
|
||||
else {
|
||||
error; // Error
|
||||
}
|
||||
function narrowsToNever(x) {
|
||||
var v;
|
||||
if ("l" in x) {
|
||||
v = x.l;
|
||||
}
|
||||
else if ("r" in x) {
|
||||
v = x.r;
|
||||
}
|
||||
else {
|
||||
v = x;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
if (isAOrB(x)) {
|
||||
if ("aProp" in x) {
|
||||
x.aProp;
|
||||
}
|
||||
else if ("bProp" in x) {
|
||||
x.bProp;
|
||||
}
|
||||
// x is never because of the type predicate from unknown
|
||||
else if ("cProp" in x) {
|
||||
var _never = x;
|
||||
}
|
||||
}
|
||||
function negativeIntersectionTest() {
|
||||
if ("ontouchstart" in window) {
|
||||
window.ontouchstart;
|
||||
|
||||
@ -261,8 +261,105 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 98, 34))
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #38608
|
||||
declare const error: Error;
|
||||
>error : Symbol(error, Decl(inKeywordTypeguard.ts, 107, 13))
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
if ('extra' in error) {
|
||||
>error : Symbol(error, Decl(inKeywordTypeguard.ts, 107, 13))
|
||||
|
||||
error // Still Error
|
||||
>error : Symbol(error, Decl(inKeywordTypeguard.ts, 107, 13))
|
||||
|
||||
} else {
|
||||
error // Error
|
||||
>error : Symbol(error, Decl(inKeywordTypeguard.ts, 107, 13))
|
||||
}
|
||||
|
||||
function narrowsToNever(x: { l: number } | { r: number }) {
|
||||
>narrowsToNever : Symbol(narrowsToNever, Decl(inKeywordTypeguard.ts, 112, 1))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24))
|
||||
>l : Symbol(l, Decl(inKeywordTypeguard.ts, 114, 28))
|
||||
>r : Symbol(r, Decl(inKeywordTypeguard.ts, 114, 44))
|
||||
|
||||
let v: number;
|
||||
>v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7))
|
||||
|
||||
if ("l" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24))
|
||||
|
||||
v = x.l;
|
||||
>v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7))
|
||||
>x.l : Symbol(l, Decl(inKeywordTypeguard.ts, 114, 28))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24))
|
||||
>l : Symbol(l, Decl(inKeywordTypeguard.ts, 114, 28))
|
||||
}
|
||||
else if ("r" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24))
|
||||
|
||||
v = x.r;
|
||||
>v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7))
|
||||
>x.r : Symbol(r, Decl(inKeywordTypeguard.ts, 114, 44))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24))
|
||||
>r : Symbol(r, Decl(inKeywordTypeguard.ts, 114, 44))
|
||||
}
|
||||
else {
|
||||
v = x
|
||||
>v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 114, 24))
|
||||
}
|
||||
return v;
|
||||
>v : Symbol(v, Decl(inKeywordTypeguard.ts, 115, 7))
|
||||
}
|
||||
|
||||
type AOrB = { aProp: number } | { bProp: number };
|
||||
>AOrB : Symbol(AOrB, Decl(inKeywordTypeguard.ts, 126, 1))
|
||||
>aProp : Symbol(aProp, Decl(inKeywordTypeguard.ts, 128, 13))
|
||||
>bProp : Symbol(bProp, Decl(inKeywordTypeguard.ts, 128, 33))
|
||||
|
||||
declare function isAOrB(x: unknown): x is AOrB;
|
||||
>isAOrB : Symbol(isAOrB, Decl(inKeywordTypeguard.ts, 128, 50))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 129, 24))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 129, 24))
|
||||
>AOrB : Symbol(AOrB, Decl(inKeywordTypeguard.ts, 126, 1))
|
||||
|
||||
declare var x: unknown;
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11))
|
||||
|
||||
if (isAOrB(x)) {
|
||||
>isAOrB : Symbol(isAOrB, Decl(inKeywordTypeguard.ts, 128, 50))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11))
|
||||
|
||||
if ("aProp" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11))
|
||||
|
||||
x.aProp;
|
||||
>x.aProp : Symbol(aProp, Decl(inKeywordTypeguard.ts, 128, 13))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11))
|
||||
>aProp : Symbol(aProp, Decl(inKeywordTypeguard.ts, 128, 13))
|
||||
}
|
||||
else if ("bProp" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11))
|
||||
|
||||
x.bProp;
|
||||
>x.bProp : Symbol(bProp, Decl(inKeywordTypeguard.ts, 128, 33))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11))
|
||||
>bProp : Symbol(bProp, Decl(inKeywordTypeguard.ts, 128, 33))
|
||||
}
|
||||
// x is never because of the type predicate from unknown
|
||||
else if ("cProp" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11))
|
||||
|
||||
const _never: never = x;
|
||||
>_never : Symbol(_never, Decl(inKeywordTypeguard.ts, 141, 13))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 131, 11))
|
||||
}
|
||||
}
|
||||
|
||||
function negativeIntersectionTest() {
|
||||
>negativeIntersectionTest : Symbol(negativeIntersectionTest, Decl(inKeywordTypeguard.ts, 104, 1))
|
||||
>negativeIntersectionTest : Symbol(negativeIntersectionTest, Decl(inKeywordTypeguard.ts, 143, 1))
|
||||
|
||||
if ("ontouchstart" in window) {
|
||||
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
@ -321,6 +321,116 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) {
|
||||
>x : never
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #38608
|
||||
declare const error: Error;
|
||||
>error : Error
|
||||
|
||||
if ('extra' in error) {
|
||||
>'extra' in error : boolean
|
||||
>'extra' : "extra"
|
||||
>error : Error
|
||||
|
||||
error // Still Error
|
||||
>error : Error
|
||||
|
||||
} else {
|
||||
error // Error
|
||||
>error : Error
|
||||
}
|
||||
|
||||
function narrowsToNever(x: { l: number } | { r: number }) {
|
||||
>narrowsToNever : (x: { l: number;} | { r: number;}) => number
|
||||
>x : { l: number; } | { r: number; }
|
||||
>l : number
|
||||
>r : number
|
||||
|
||||
let v: number;
|
||||
>v : number
|
||||
|
||||
if ("l" in x) {
|
||||
>"l" in x : boolean
|
||||
>"l" : "l"
|
||||
>x : { l: number; } | { r: number; }
|
||||
|
||||
v = x.l;
|
||||
>v = x.l : number
|
||||
>v : number
|
||||
>x.l : number
|
||||
>x : { l: number; }
|
||||
>l : number
|
||||
}
|
||||
else if ("r" in x) {
|
||||
>"r" in x : boolean
|
||||
>"r" : "r"
|
||||
>x : { r: number; }
|
||||
|
||||
v = x.r;
|
||||
>v = x.r : number
|
||||
>v : number
|
||||
>x.r : number
|
||||
>x : { r: number; }
|
||||
>r : number
|
||||
}
|
||||
else {
|
||||
v = x
|
||||
>v = x : never
|
||||
>v : number
|
||||
>x : never
|
||||
}
|
||||
return v;
|
||||
>v : number
|
||||
}
|
||||
|
||||
type AOrB = { aProp: number } | { bProp: number };
|
||||
>AOrB : AOrB
|
||||
>aProp : number
|
||||
>bProp : number
|
||||
|
||||
declare function isAOrB(x: unknown): x is AOrB;
|
||||
>isAOrB : (x: unknown) => x is AOrB
|
||||
>x : unknown
|
||||
|
||||
declare var x: unknown;
|
||||
>x : unknown
|
||||
|
||||
if (isAOrB(x)) {
|
||||
>isAOrB(x) : boolean
|
||||
>isAOrB : (x: unknown) => x is AOrB
|
||||
>x : unknown
|
||||
|
||||
if ("aProp" in x) {
|
||||
>"aProp" in x : boolean
|
||||
>"aProp" : "aProp"
|
||||
>x : AOrB
|
||||
|
||||
x.aProp;
|
||||
>x.aProp : number
|
||||
>x : { aProp: number; }
|
||||
>aProp : number
|
||||
}
|
||||
else if ("bProp" in x) {
|
||||
>"bProp" in x : boolean
|
||||
>"bProp" : "bProp"
|
||||
>x : { bProp: number; }
|
||||
|
||||
x.bProp;
|
||||
>x.bProp : number
|
||||
>x : { bProp: number; }
|
||||
>bProp : number
|
||||
}
|
||||
// x is never because of the type predicate from unknown
|
||||
else if ("cProp" in x) {
|
||||
>"cProp" in x : boolean
|
||||
>"cProp" : "cProp"
|
||||
>x : never
|
||||
|
||||
const _never: never = x;
|
||||
>_never : never
|
||||
>x : never
|
||||
}
|
||||
}
|
||||
|
||||
function negativeIntersectionTest() {
|
||||
>negativeIntersectionTest : () => void
|
||||
|
||||
|
||||
@ -103,6 +103,46 @@ function positiveIntersectionTest(x: { a: string } & { b: string }) {
|
||||
let n: never = x;
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #38608
|
||||
declare const error: Error;
|
||||
if ('extra' in error) {
|
||||
error // Still Error
|
||||
} else {
|
||||
error // Error
|
||||
}
|
||||
|
||||
function narrowsToNever(x: { l: number } | { r: number }) {
|
||||
let v: number;
|
||||
if ("l" in x) {
|
||||
v = x.l;
|
||||
}
|
||||
else if ("r" in x) {
|
||||
v = x.r;
|
||||
}
|
||||
else {
|
||||
v = x
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
type AOrB = { aProp: number } | { bProp: number };
|
||||
declare function isAOrB(x: unknown): x is AOrB;
|
||||
|
||||
declare var x: unknown;
|
||||
if (isAOrB(x)) {
|
||||
if ("aProp" in x) {
|
||||
x.aProp;
|
||||
}
|
||||
else if ("bProp" in x) {
|
||||
x.bProp;
|
||||
}
|
||||
// x is never because of the type predicate from unknown
|
||||
else if ("cProp" in x) {
|
||||
const _never: never = x;
|
||||
}
|
||||
}
|
||||
|
||||
function negativeIntersectionTest() {
|
||||
if ("ontouchstart" in window) {
|
||||
window.ontouchstart
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user