Add missing BinaryExpression source side cases to isMatchingReference (#41765)

This commit is contained in:
Wesley Wigham 2020-12-01 14:47:14 -08:00 committed by GitHub
parent 4d6947ae14
commit 0da5a7e4ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 182 additions and 0 deletions

View File

@ -20857,6 +20857,8 @@ namespace ts {
return isAccessExpression(target) &&
getAccessedPropertyName(<AccessExpression>source) === getAccessedPropertyName(target) &&
isMatchingReference((<AccessExpression>source).expression, target.expression);
case SyntaxKind.BinaryExpression:
return (isBinaryExpression(source) && source.operatorToken.kind === SyntaxKind.CommaToken && isMatchingReference(source.right, target));
}
return false;
}

View File

@ -0,0 +1,32 @@
//// [narrowCommaOperatorNestedWithinLHS.ts]
const otherValue = () => true;
const value: { inner: number | string } = null as any;
function isNumber(obj: any): obj is number {
return true; // method implementation irrelevant
}
if (typeof (otherValue(), value).inner === 'number') {
const a = value.inner; // number
const b: number = (otherValue(), value).inner; // string | number , but should be number
}
if (isNumber((otherValue(), value).inner)) {
const a = value.inner; // number
const b: number = (otherValue(), value).inner; // string | number , but should be number
}
//// [narrowCommaOperatorNestedWithinLHS.js]
var otherValue = function () { return true; };
var value = null;
function isNumber(obj) {
return true; // method implementation irrelevant
}
if (typeof (otherValue(), value).inner === 'number') {
var a = value.inner; // number
var b = (otherValue(), value).inner; // string | number , but should be number
}
if (isNumber((otherValue(), value).inner)) {
var a = value.inner; // number
var b = (otherValue(), value).inner; // string | number , but should be number
}

View File

@ -0,0 +1,56 @@
=== tests/cases/compiler/narrowCommaOperatorNestedWithinLHS.ts ===
const otherValue = () => true;
>otherValue : Symbol(otherValue, Decl(narrowCommaOperatorNestedWithinLHS.ts, 0, 5))
const value: { inner: number | string } = null as any;
>value : Symbol(value, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 5))
>inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
function isNumber(obj: any): obj is number {
>isNumber : Symbol(isNumber, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 54))
>obj : Symbol(obj, Decl(narrowCommaOperatorNestedWithinLHS.ts, 3, 18))
>obj : Symbol(obj, Decl(narrowCommaOperatorNestedWithinLHS.ts, 3, 18))
return true; // method implementation irrelevant
}
if (typeof (otherValue(), value).inner === 'number') {
>(otherValue(), value).inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
>otherValue : Symbol(otherValue, Decl(narrowCommaOperatorNestedWithinLHS.ts, 0, 5))
>value : Symbol(value, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 5))
>inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
const a = value.inner; // number
>a : Symbol(a, Decl(narrowCommaOperatorNestedWithinLHS.ts, 8, 9))
>value.inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
>value : Symbol(value, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 5))
>inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
const b: number = (otherValue(), value).inner; // string | number , but should be number
>b : Symbol(b, Decl(narrowCommaOperatorNestedWithinLHS.ts, 9, 9))
>(otherValue(), value).inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
>otherValue : Symbol(otherValue, Decl(narrowCommaOperatorNestedWithinLHS.ts, 0, 5))
>value : Symbol(value, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 5))
>inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
}
if (isNumber((otherValue(), value).inner)) {
>isNumber : Symbol(isNumber, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 54))
>(otherValue(), value).inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
>otherValue : Symbol(otherValue, Decl(narrowCommaOperatorNestedWithinLHS.ts, 0, 5))
>value : Symbol(value, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 5))
>inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
const a = value.inner; // number
>a : Symbol(a, Decl(narrowCommaOperatorNestedWithinLHS.ts, 13, 9))
>value.inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
>value : Symbol(value, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 5))
>inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
const b: number = (otherValue(), value).inner; // string | number , but should be number
>b : Symbol(b, Decl(narrowCommaOperatorNestedWithinLHS.ts, 14, 9))
>(otherValue(), value).inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
>otherValue : Symbol(otherValue, Decl(narrowCommaOperatorNestedWithinLHS.ts, 0, 5))
>value : Symbol(value, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 5))
>inner : Symbol(inner, Decl(narrowCommaOperatorNestedWithinLHS.ts, 1, 14))
}

View File

@ -0,0 +1,76 @@
=== tests/cases/compiler/narrowCommaOperatorNestedWithinLHS.ts ===
const otherValue = () => true;
>otherValue : () => boolean
>() => true : () => boolean
>true : true
const value: { inner: number | string } = null as any;
>value : { inner: number | string; }
>inner : string | number
>null as any : any
>null : null
function isNumber(obj: any): obj is number {
>isNumber : (obj: any) => obj is number
>obj : any
return true; // method implementation irrelevant
>true : true
}
if (typeof (otherValue(), value).inner === 'number') {
>typeof (otherValue(), value).inner === 'number' : boolean
>typeof (otherValue(), value).inner : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>(otherValue(), value).inner : string | number
>(otherValue(), value) : { inner: string | number; }
>otherValue(), value : { inner: string | number; }
>otherValue() : boolean
>otherValue : () => boolean
>value : { inner: string | number; }
>inner : string | number
>'number' : "number"
const a = value.inner; // number
>a : number
>value.inner : number
>value : { inner: string | number; }
>inner : number
const b: number = (otherValue(), value).inner; // string | number , but should be number
>b : number
>(otherValue(), value).inner : number
>(otherValue(), value) : { inner: string | number; }
>otherValue(), value : { inner: string | number; }
>otherValue() : boolean
>otherValue : () => boolean
>value : { inner: string | number; }
>inner : number
}
if (isNumber((otherValue(), value).inner)) {
>isNumber((otherValue(), value).inner) : boolean
>isNumber : (obj: any) => obj is number
>(otherValue(), value).inner : string | number
>(otherValue(), value) : { inner: string | number; }
>otherValue(), value : { inner: string | number; }
>otherValue() : boolean
>otherValue : () => boolean
>value : { inner: string | number; }
>inner : string | number
const a = value.inner; // number
>a : number
>value.inner : number
>value : { inner: string | number; }
>inner : number
const b: number = (otherValue(), value).inner; // string | number , but should be number
>b : number
>(otherValue(), value).inner : number
>(otherValue(), value) : { inner: string | number; }
>otherValue(), value : { inner: string | number; }
>otherValue() : boolean
>otherValue : () => boolean
>value : { inner: string | number; }
>inner : number
}

View File

@ -0,0 +1,16 @@
const otherValue = () => true;
const value: { inner: number | string } = null as any;
function isNumber(obj: any): obj is number {
return true; // method implementation irrelevant
}
if (typeof (otherValue(), value).inner === 'number') {
const a = value.inner; // number
const b: number = (otherValue(), value).inner; // string | number , but should be number
}
if (isNumber((otherValue(), value).inner)) {
const a = value.inner; // number
const b: number = (otherValue(), value).inner; // string | number , but should be number
}