Add type narrow

This commit is contained in:
kingwl 2020-04-08 12:09:56 +08:00
parent 67a4943e1f
commit d2be8900dc
15 changed files with 694 additions and 102 deletions

View File

@ -905,6 +905,9 @@ namespace ts {
function isNarrowingBinaryExpression(expr: BinaryExpression) {
switch (expr.operatorToken.kind) {
case SyntaxKind.EqualsToken:
case SyntaxKind.BarBarEqualsToken:
case SyntaxKind.AmpersandAmpersandEqualsToken:
case SyntaxKind.QuestionQuestionEqualsToken:
return containsNarrowableReference(expr.left);
case SyntaxKind.EqualsEqualsToken:
case SyntaxKind.ExclamationEqualsToken:

View File

@ -20701,7 +20701,11 @@ namespace ts {
function narrowTypeByBinaryExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
switch (expr.operatorToken.kind) {
case SyntaxKind.EqualsToken:
case SyntaxKind.BarBarEqualsToken:
case SyntaxKind.AmpersandAmpersandEqualsToken:
case SyntaxKind.QuestionQuestionEqualsToken:
return narrowTypeByTruthiness(narrowType(type, expr.right, assumeTrue), expr.left, assumeTrue);
case SyntaxKind.EqualsEqualsToken:
case SyntaxKind.ExclamationEqualsToken:
case SyntaxKind.EqualsEqualsEqualsToken:

View File

@ -1,7 +1,8 @@
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(25,21): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(39,13): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(45,13): error TS2532: Object is possibly 'undefined'.
==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts (1 errors) ====
==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts (2 errors) ====
function foo1(results: number[] | undefined) {
(results ||= []).push(100);
}
@ -24,10 +25,33 @@ tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(25,21): e
name: string;
original?: ThingWithOriginal
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
if (thing &&= thing.original) {
console.log(thing.name);
~~~~~
declare const v: number
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
if (v === 1) {
if (thing &&= thing.original) {
thing.name;
}
}
else if (v === 2) {
if (thing &&= defaultValue) {
thing.name;
defaultValue.name
}
}
else if (v === 3) {
if (thing ||= defaultValue) {
thing.name;
defaultValue.name;
~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
}
}
else {
if (thing ??= defaultValue) {
thing.name;
defaultValue.name;
~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
}
}
}

View File

@ -21,9 +21,30 @@ interface ThingWithOriginal {
name: string;
original?: ThingWithOriginal
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
if (thing &&= thing.original) {
console.log(thing.name);
declare const v: number
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
if (v === 1) {
if (thing &&= thing.original) {
thing.name;
}
}
else if (v === 2) {
if (thing &&= defaultValue) {
thing.name;
defaultValue.name
}
}
else if (v === 3) {
if (thing ||= defaultValue) {
thing.name;
defaultValue.name;
}
}
else {
if (thing ??= defaultValue) {
thing.name;
defaultValue.name;
}
}
}
@ -43,8 +64,28 @@ function foo4(results) {
results !== null && results !== void 0 ? results : (results = []);
results.push(100);
}
function doSomethingWithAlias(thing) {
if (thing && (thing = thing.original)) {
console.log(thing.name);
function doSomethingWithAlias(thing, defaultValue) {
if (v === 1) {
if (thing && (thing = thing.original)) {
thing.name;
}
}
else if (v === 2) {
if (thing && (thing = defaultValue)) {
thing.name;
defaultValue.name;
}
}
else if (v === 3) {
if (thing || (thing = defaultValue)) {
thing.name;
defaultValue.name;
}
}
else {
if (thing !== null && thing !== void 0 ? thing : (thing = defaultValue)) {
thing.name;
defaultValue.name;
}
}
}

View File

@ -55,23 +55,81 @@ interface ThingWithOriginal {
>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17))
>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1))
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
>doSomethingWithAlias : Symbol(doSomethingWithAlias, Decl(logicalAssignment4.ts, 21, 1))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
declare const v: number
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
>doSomethingWithAlias : Symbol(doSomethingWithAlias, Decl(logicalAssignment4.ts, 22, 23))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1))
if (thing &&= thing.original) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
if (v === 1) {
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
if (thing &&= thing.original) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>thing.original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17))
console.log(thing.name);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
else if (v === 2) {
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
if (thing &&= defaultValue) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
defaultValue.name
>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
else if (v === 3) {
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
if (thing ||= defaultValue) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
defaultValue.name;
>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
else {
if (thing ??= defaultValue) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
defaultValue.name;
>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
}

View File

@ -70,24 +70,89 @@ interface ThingWithOriginal {
original?: ThingWithOriginal
>original : ThingWithOriginal | undefined
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
>doSomethingWithAlias : (thing?: ThingWithOriginal | undefined) => void
>thing : ThingWithOriginal | undefined
declare const v: number
>v : number
if (thing &&= thing.original) {
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
>doSomethingWithAlias : (thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) => void
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
if (v === 1) {
>v === 1 : boolean
>v : number
>1 : 1
if (thing &&= thing.original) {
>thing &&= thing.original : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>thing.original : ThingWithOriginal | undefined
>thing : ThingWithOriginal
>original : ThingWithOriginal | undefined
console.log(thing.name);
>console.log(thing.name) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
thing.name;
>thing.name : string
>thing : ThingWithOriginal | undefined
>thing : ThingWithOriginal
>name : string
}
}
else if (v === 2) {
>v === 2 : boolean
>v : number
>2 : 2
if (thing &&= defaultValue) {
>thing &&= defaultValue : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
thing.name;
>thing.name : string
>thing : ThingWithOriginal
>name : string
defaultValue.name
>defaultValue.name : string
>defaultValue : ThingWithOriginal
>name : string
}
}
else if (v === 3) {
>v === 3 : boolean
>v : number
>3 : 3
if (thing ||= defaultValue) {
>thing ||= defaultValue : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
thing.name;
>thing.name : string
>thing : ThingWithOriginal
>name : string
defaultValue.name;
>defaultValue.name : string
>defaultValue : ThingWithOriginal | undefined
>name : string
}
}
else {
if (thing ??= defaultValue) {
>thing ??= defaultValue : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
thing.name;
>thing.name : string
>thing : ThingWithOriginal
>name : string
defaultValue.name;
>defaultValue.name : string
>defaultValue : ThingWithOriginal | undefined
>name : string
}
}
}

View File

@ -1,7 +1,8 @@
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(25,21): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(39,13): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(45,13): error TS2532: Object is possibly 'undefined'.
==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts (1 errors) ====
==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts (2 errors) ====
function foo1(results: number[] | undefined) {
(results ||= []).push(100);
}
@ -24,10 +25,33 @@ tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(25,21): e
name: string;
original?: ThingWithOriginal
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
if (thing &&= thing.original) {
console.log(thing.name);
~~~~~
declare const v: number
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
if (v === 1) {
if (thing &&= thing.original) {
thing.name;
}
}
else if (v === 2) {
if (thing &&= defaultValue) {
thing.name;
defaultValue.name
}
}
else if (v === 3) {
if (thing ||= defaultValue) {
thing.name;
defaultValue.name;
~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
}
}
else {
if (thing ??= defaultValue) {
thing.name;
defaultValue.name;
~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
}
}
}

View File

@ -21,9 +21,30 @@ interface ThingWithOriginal {
name: string;
original?: ThingWithOriginal
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
if (thing &&= thing.original) {
console.log(thing.name);
declare const v: number
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
if (v === 1) {
if (thing &&= thing.original) {
thing.name;
}
}
else if (v === 2) {
if (thing &&= defaultValue) {
thing.name;
defaultValue.name
}
}
else if (v === 3) {
if (thing ||= defaultValue) {
thing.name;
defaultValue.name;
}
}
else {
if (thing ??= defaultValue) {
thing.name;
defaultValue.name;
}
}
}
@ -43,8 +64,28 @@ function foo4(results) {
results ?? (results = []);
results.push(100);
}
function doSomethingWithAlias(thing) {
if (thing && (thing = thing.original)) {
console.log(thing.name);
function doSomethingWithAlias(thing, defaultValue) {
if (v === 1) {
if (thing && (thing = thing.original)) {
thing.name;
}
}
else if (v === 2) {
if (thing && (thing = defaultValue)) {
thing.name;
defaultValue.name;
}
}
else if (v === 3) {
if (thing || (thing = defaultValue)) {
thing.name;
defaultValue.name;
}
}
else {
if (thing ?? (thing = defaultValue)) {
thing.name;
defaultValue.name;
}
}
}

View File

@ -55,23 +55,81 @@ interface ThingWithOriginal {
>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17))
>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1))
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
>doSomethingWithAlias : Symbol(doSomethingWithAlias, Decl(logicalAssignment4.ts, 21, 1))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
declare const v: number
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
>doSomethingWithAlias : Symbol(doSomethingWithAlias, Decl(logicalAssignment4.ts, 22, 23))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1))
if (thing &&= thing.original) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
if (v === 1) {
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
if (thing &&= thing.original) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>thing.original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17))
console.log(thing.name);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
else if (v === 2) {
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
if (thing &&= defaultValue) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
defaultValue.name
>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
else if (v === 3) {
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
if (thing ||= defaultValue) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
defaultValue.name;
>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
else {
if (thing ??= defaultValue) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
defaultValue.name;
>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
}

View File

@ -70,24 +70,89 @@ interface ThingWithOriginal {
original?: ThingWithOriginal
>original : ThingWithOriginal | undefined
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
>doSomethingWithAlias : (thing?: ThingWithOriginal | undefined) => void
>thing : ThingWithOriginal | undefined
declare const v: number
>v : number
if (thing &&= thing.original) {
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
>doSomethingWithAlias : (thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) => void
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
if (v === 1) {
>v === 1 : boolean
>v : number
>1 : 1
if (thing &&= thing.original) {
>thing &&= thing.original : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>thing.original : ThingWithOriginal | undefined
>thing : ThingWithOriginal
>original : ThingWithOriginal | undefined
console.log(thing.name);
>console.log(thing.name) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
thing.name;
>thing.name : string
>thing : ThingWithOriginal | undefined
>thing : ThingWithOriginal
>name : string
}
}
else if (v === 2) {
>v === 2 : boolean
>v : number
>2 : 2
if (thing &&= defaultValue) {
>thing &&= defaultValue : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
thing.name;
>thing.name : string
>thing : ThingWithOriginal
>name : string
defaultValue.name
>defaultValue.name : string
>defaultValue : ThingWithOriginal
>name : string
}
}
else if (v === 3) {
>v === 3 : boolean
>v : number
>3 : 3
if (thing ||= defaultValue) {
>thing ||= defaultValue : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
thing.name;
>thing.name : string
>thing : ThingWithOriginal
>name : string
defaultValue.name;
>defaultValue.name : string
>defaultValue : ThingWithOriginal | undefined
>name : string
}
}
else {
if (thing ??= defaultValue) {
>thing ??= defaultValue : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
thing.name;
>thing.name : string
>thing : ThingWithOriginal
>name : string
defaultValue.name;
>defaultValue.name : string
>defaultValue : ThingWithOriginal | undefined
>name : string
}
}
}

View File

@ -1,7 +1,8 @@
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(25,21): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(39,13): error TS2532: Object is possibly 'undefined'.
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(45,13): error TS2532: Object is possibly 'undefined'.
==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts (1 errors) ====
==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts (2 errors) ====
function foo1(results: number[] | undefined) {
(results ||= []).push(100);
}
@ -24,10 +25,33 @@ tests/cases/conformance/esnext/logicalAssignment/logicalAssignment4.ts(25,21): e
name: string;
original?: ThingWithOriginal
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
if (thing &&= thing.original) {
console.log(thing.name);
~~~~~
declare const v: number
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
if (v === 1) {
if (thing &&= thing.original) {
thing.name;
}
}
else if (v === 2) {
if (thing &&= defaultValue) {
thing.name;
defaultValue.name
}
}
else if (v === 3) {
if (thing ||= defaultValue) {
thing.name;
defaultValue.name;
~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
}
}
else {
if (thing ??= defaultValue) {
thing.name;
defaultValue.name;
~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
}
}
}

View File

@ -21,9 +21,30 @@ interface ThingWithOriginal {
name: string;
original?: ThingWithOriginal
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
if (thing &&= thing.original) {
console.log(thing.name);
declare const v: number
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
if (v === 1) {
if (thing &&= thing.original) {
thing.name;
}
}
else if (v === 2) {
if (thing &&= defaultValue) {
thing.name;
defaultValue.name
}
}
else if (v === 3) {
if (thing ||= defaultValue) {
thing.name;
defaultValue.name;
}
}
else {
if (thing ??= defaultValue) {
thing.name;
defaultValue.name;
}
}
}
@ -43,8 +64,28 @@ function foo4(results) {
results ??= [];
results.push(100);
}
function doSomethingWithAlias(thing) {
if (thing &&= thing.original) {
console.log(thing.name);
function doSomethingWithAlias(thing, defaultValue) {
if (v === 1) {
if (thing &&= thing.original) {
thing.name;
}
}
else if (v === 2) {
if (thing &&= defaultValue) {
thing.name;
defaultValue.name;
}
}
else if (v === 3) {
if (thing ||= defaultValue) {
thing.name;
defaultValue.name;
}
}
else {
if (thing ??= defaultValue) {
thing.name;
defaultValue.name;
}
}
}

View File

@ -55,23 +55,81 @@ interface ThingWithOriginal {
>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17))
>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1))
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
>doSomethingWithAlias : Symbol(doSomethingWithAlias, Decl(logicalAssignment4.ts, 21, 1))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
declare const v: number
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
>doSomethingWithAlias : Symbol(doSomethingWithAlias, Decl(logicalAssignment4.ts, 22, 23))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>ThingWithOriginal : Symbol(ThingWithOriginal, Decl(logicalAssignment4.ts, 16, 1))
if (thing &&= thing.original) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
if (v === 1) {
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
if (thing &&= thing.original) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>thing.original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>original : Symbol(ThingWithOriginal.original, Decl(logicalAssignment4.ts, 19, 17))
console.log(thing.name);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 22, 30))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
else if (v === 2) {
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
if (thing &&= defaultValue) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
defaultValue.name
>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
else if (v === 3) {
>v : Symbol(v, Decl(logicalAssignment4.ts, 22, 13))
if (thing ||= defaultValue) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
defaultValue.name;
>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
else {
if (thing ??= defaultValue) {
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
thing.name;
>thing.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>thing : Symbol(thing, Decl(logicalAssignment4.ts, 23, 30))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
defaultValue.name;
>defaultValue.name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
>defaultValue : Symbol(defaultValue, Decl(logicalAssignment4.ts, 23, 67))
>name : Symbol(ThingWithOriginal.name, Decl(logicalAssignment4.ts, 18, 29))
}
}
}

View File

@ -70,24 +70,89 @@ interface ThingWithOriginal {
original?: ThingWithOriginal
>original : ThingWithOriginal | undefined
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
>doSomethingWithAlias : (thing?: ThingWithOriginal | undefined) => void
>thing : ThingWithOriginal | undefined
declare const v: number
>v : number
if (thing &&= thing.original) {
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
>doSomethingWithAlias : (thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) => void
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
if (v === 1) {
>v === 1 : boolean
>v : number
>1 : 1
if (thing &&= thing.original) {
>thing &&= thing.original : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>thing.original : ThingWithOriginal | undefined
>thing : ThingWithOriginal
>original : ThingWithOriginal | undefined
console.log(thing.name);
>console.log(thing.name) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
thing.name;
>thing.name : string
>thing : ThingWithOriginal | undefined
>thing : ThingWithOriginal
>name : string
}
}
else if (v === 2) {
>v === 2 : boolean
>v : number
>2 : 2
if (thing &&= defaultValue) {
>thing &&= defaultValue : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
thing.name;
>thing.name : string
>thing : ThingWithOriginal
>name : string
defaultValue.name
>defaultValue.name : string
>defaultValue : ThingWithOriginal
>name : string
}
}
else if (v === 3) {
>v === 3 : boolean
>v : number
>3 : 3
if (thing ||= defaultValue) {
>thing ||= defaultValue : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
thing.name;
>thing.name : string
>thing : ThingWithOriginal
>name : string
defaultValue.name;
>defaultValue.name : string
>defaultValue : ThingWithOriginal | undefined
>name : string
}
}
else {
if (thing ??= defaultValue) {
>thing ??= defaultValue : ThingWithOriginal | undefined
>thing : ThingWithOriginal | undefined
>defaultValue : ThingWithOriginal | undefined
thing.name;
>thing.name : string
>thing : ThingWithOriginal
>name : string
defaultValue.name;
>defaultValue.name : string
>defaultValue : ThingWithOriginal | undefined
>name : string
}
}
}

View File

@ -24,8 +24,29 @@ interface ThingWithOriginal {
name: string;
original?: ThingWithOriginal
}
function doSomethingWithAlias(thing?: ThingWithOriginal | undefined) {
if (thing &&= thing.original) {
console.log(thing.name);
declare const v: number
function doSomethingWithAlias(thing: ThingWithOriginal | undefined, defaultValue: ThingWithOriginal | undefined) {
if (v === 1) {
if (thing &&= thing.original) {
thing.name;
}
}
else if (v === 2) {
if (thing &&= defaultValue) {
thing.name;
defaultValue.name
}
}
else if (v === 3) {
if (thing ||= defaultValue) {
thing.name;
defaultValue.name;
}
}
else {
if (thing ??= defaultValue) {
thing.name;
defaultValue.name;
}
}
}