Add more case

This commit is contained in:
kingwl 2020-04-04 22:19:57 +08:00
parent 81ce254a73
commit 67a4943e1f
14 changed files with 466 additions and 6 deletions

View File

@ -905,9 +905,6 @@ 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:
@ -932,9 +929,6 @@ namespace ts {
case SyntaxKind.BinaryExpression:
switch ((<BinaryExpression>expr).operatorToken.kind) {
case SyntaxKind.EqualsToken:
case SyntaxKind.BarBarEqualsToken:
case SyntaxKind.AmpersandAmpersandEqualsToken:
case SyntaxKind.QuestionQuestionEqualsToken:
return isNarrowableOperand((<BinaryExpression>expr).left);
case SyntaxKind.CommaToken:
return isNarrowableOperand((<BinaryExpression>expr).right);

View File

@ -0,0 +1,19 @@
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts(12,5): error TS2532: Object is possibly 'undefined'.
==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts (1 errors) ====
declare const bar: { value?: number[] } | undefined
function foo1(results: number[] | undefined) {
(results ||= bar?.value ?? []).push(100);
}
function foo2(results: number[] | undefined) {
(results ??= bar?.value ?? []).push(100);
}
function foo3(results: number[] | undefined) {
(results &&= bar?.value ?? []).push(100);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
}

View File

@ -0,0 +1,29 @@
//// [logicalAssignment8.ts]
declare const bar: { value?: number[] } | undefined
function foo1(results: number[] | undefined) {
(results ||= bar?.value ?? []).push(100);
}
function foo2(results: number[] | undefined) {
(results ??= bar?.value ?? []).push(100);
}
function foo3(results: number[] | undefined) {
(results &&= bar?.value ?? []).push(100);
}
//// [logicalAssignment8.js]
"use strict";
function foo1(results) {
var _a;
(results || (results = (_a = bar === null || bar === void 0 ? void 0 : bar.value) !== null && _a !== void 0 ? _a : [])).push(100);
}
function foo2(results) {
var _a;
(results !== null && results !== void 0 ? results : (results = (_a = bar === null || bar === void 0 ? void 0 : bar.value) !== null && _a !== void 0 ? _a : [])).push(100);
}
function foo3(results) {
var _a;
(results && (results = (_a = bar === null || bar === void 0 ? void 0 : bar.value) !== null && _a !== void 0 ? _a : [])).push(100);
}

View File

@ -0,0 +1,43 @@
=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts ===
declare const bar: { value?: number[] } | undefined
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
function foo1(results: number[] | undefined) {
>foo1 : Symbol(foo1, Decl(logicalAssignment8.ts, 0, 51))
>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14))
(results ||= bar?.value ?? []).push(100);
>(results ||= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14))
>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
}
function foo2(results: number[] | undefined) {
>foo2 : Symbol(foo2, Decl(logicalAssignment8.ts, 4, 1))
>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14))
(results ??= bar?.value ?? []).push(100);
>(results ??= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14))
>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
}
function foo3(results: number[] | undefined) {
>foo3 : Symbol(foo3, Decl(logicalAssignment8.ts, 8, 1))
>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14))
(results &&= bar?.value ?? []).push(100);
>(results &&= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14))
>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
}

View File

@ -0,0 +1,61 @@
=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts ===
declare const bar: { value?: number[] } | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
function foo1(results: number[] | undefined) {
>foo1 : (results: number[] | undefined) => void
>results : number[] | undefined
(results ||= bar?.value ?? []).push(100);
>(results ||= bar?.value ?? []).push(100) : number
>(results ||= bar?.value ?? []).push : (...items: number[]) => number
>(results ||= bar?.value ?? []) : number[]
>results ||= bar?.value ?? [] : number[]
>results : number[] | undefined
>bar?.value ?? [] : number[]
>bar?.value : number[] | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
>[] : never[]
>push : (...items: number[]) => number
>100 : 100
}
function foo2(results: number[] | undefined) {
>foo2 : (results: number[] | undefined) => void
>results : number[] | undefined
(results ??= bar?.value ?? []).push(100);
>(results ??= bar?.value ?? []).push(100) : number
>(results ??= bar?.value ?? []).push : (...items: number[]) => number
>(results ??= bar?.value ?? []) : number[]
>results ??= bar?.value ?? [] : number[]
>results : number[] | undefined
>bar?.value ?? [] : number[]
>bar?.value : number[] | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
>[] : never[]
>push : (...items: number[]) => number
>100 : 100
}
function foo3(results: number[] | undefined) {
>foo3 : (results: number[] | undefined) => void
>results : number[] | undefined
(results &&= bar?.value ?? []).push(100);
>(results &&= bar?.value ?? []).push(100) : number
>(results &&= bar?.value ?? []).push : (...items: number[]) => number
>(results &&= bar?.value ?? []) : number[] | undefined
>results &&= bar?.value ?? [] : number[] | undefined
>results : number[] | undefined
>bar?.value ?? [] : number[]
>bar?.value : number[] | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
>[] : never[]
>push : (...items: number[]) => number
>100 : 100
}

View File

@ -0,0 +1,19 @@
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts(12,5): error TS2532: Object is possibly 'undefined'.
==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts (1 errors) ====
declare const bar: { value?: number[] } | undefined
function foo1(results: number[] | undefined) {
(results ||= bar?.value ?? []).push(100);
}
function foo2(results: number[] | undefined) {
(results ??= bar?.value ?? []).push(100);
}
function foo3(results: number[] | undefined) {
(results &&= bar?.value ?? []).push(100);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
}

View File

@ -0,0 +1,26 @@
//// [logicalAssignment8.ts]
declare const bar: { value?: number[] } | undefined
function foo1(results: number[] | undefined) {
(results ||= bar?.value ?? []).push(100);
}
function foo2(results: number[] | undefined) {
(results ??= bar?.value ?? []).push(100);
}
function foo3(results: number[] | undefined) {
(results &&= bar?.value ?? []).push(100);
}
//// [logicalAssignment8.js]
"use strict";
function foo1(results) {
(results || (results = bar?.value ?? [])).push(100);
}
function foo2(results) {
(results ?? (results = bar?.value ?? [])).push(100);
}
function foo3(results) {
(results && (results = bar?.value ?? [])).push(100);
}

View File

@ -0,0 +1,43 @@
=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts ===
declare const bar: { value?: number[] } | undefined
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
function foo1(results: number[] | undefined) {
>foo1 : Symbol(foo1, Decl(logicalAssignment8.ts, 0, 51))
>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14))
(results ||= bar?.value ?? []).push(100);
>(results ||= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14))
>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
}
function foo2(results: number[] | undefined) {
>foo2 : Symbol(foo2, Decl(logicalAssignment8.ts, 4, 1))
>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14))
(results ??= bar?.value ?? []).push(100);
>(results ??= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14))
>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
}
function foo3(results: number[] | undefined) {
>foo3 : Symbol(foo3, Decl(logicalAssignment8.ts, 8, 1))
>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14))
(results &&= bar?.value ?? []).push(100);
>(results &&= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14))
>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
}

View File

@ -0,0 +1,61 @@
=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts ===
declare const bar: { value?: number[] } | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
function foo1(results: number[] | undefined) {
>foo1 : (results: number[] | undefined) => void
>results : number[] | undefined
(results ||= bar?.value ?? []).push(100);
>(results ||= bar?.value ?? []).push(100) : number
>(results ||= bar?.value ?? []).push : (...items: number[]) => number
>(results ||= bar?.value ?? []) : number[]
>results ||= bar?.value ?? [] : number[]
>results : number[] | undefined
>bar?.value ?? [] : number[]
>bar?.value : number[] | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
>[] : never[]
>push : (...items: number[]) => number
>100 : 100
}
function foo2(results: number[] | undefined) {
>foo2 : (results: number[] | undefined) => void
>results : number[] | undefined
(results ??= bar?.value ?? []).push(100);
>(results ??= bar?.value ?? []).push(100) : number
>(results ??= bar?.value ?? []).push : (...items: number[]) => number
>(results ??= bar?.value ?? []) : number[]
>results ??= bar?.value ?? [] : number[]
>results : number[] | undefined
>bar?.value ?? [] : number[]
>bar?.value : number[] | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
>[] : never[]
>push : (...items: number[]) => number
>100 : 100
}
function foo3(results: number[] | undefined) {
>foo3 : (results: number[] | undefined) => void
>results : number[] | undefined
(results &&= bar?.value ?? []).push(100);
>(results &&= bar?.value ?? []).push(100) : number
>(results &&= bar?.value ?? []).push : (...items: number[]) => number
>(results &&= bar?.value ?? []) : number[] | undefined
>results &&= bar?.value ?? [] : number[] | undefined
>results : number[] | undefined
>bar?.value ?? [] : number[]
>bar?.value : number[] | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
>[] : never[]
>push : (...items: number[]) => number
>100 : 100
}

View File

@ -0,0 +1,19 @@
tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts(12,5): error TS2532: Object is possibly 'undefined'.
==== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts (1 errors) ====
declare const bar: { value?: number[] } | undefined
function foo1(results: number[] | undefined) {
(results ||= bar?.value ?? []).push(100);
}
function foo2(results: number[] | undefined) {
(results ??= bar?.value ?? []).push(100);
}
function foo3(results: number[] | undefined) {
(results &&= bar?.value ?? []).push(100);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2532: Object is possibly 'undefined'.
}

View File

@ -0,0 +1,26 @@
//// [logicalAssignment8.ts]
declare const bar: { value?: number[] } | undefined
function foo1(results: number[] | undefined) {
(results ||= bar?.value ?? []).push(100);
}
function foo2(results: number[] | undefined) {
(results ??= bar?.value ?? []).push(100);
}
function foo3(results: number[] | undefined) {
(results &&= bar?.value ?? []).push(100);
}
//// [logicalAssignment8.js]
"use strict";
function foo1(results) {
(results ||= bar?.value ?? []).push(100);
}
function foo2(results) {
(results ??= bar?.value ?? []).push(100);
}
function foo3(results) {
(results &&= bar?.value ?? []).push(100);
}

View File

@ -0,0 +1,43 @@
=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts ===
declare const bar: { value?: number[] } | undefined
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
function foo1(results: number[] | undefined) {
>foo1 : Symbol(foo1, Decl(logicalAssignment8.ts, 0, 51))
>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14))
(results ||= bar?.value ?? []).push(100);
>(results ||= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>results : Symbol(results, Decl(logicalAssignment8.ts, 2, 14))
>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
}
function foo2(results: number[] | undefined) {
>foo2 : Symbol(foo2, Decl(logicalAssignment8.ts, 4, 1))
>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14))
(results ??= bar?.value ?? []).push(100);
>(results ??= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>results : Symbol(results, Decl(logicalAssignment8.ts, 6, 14))
>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
}
function foo3(results: number[] | undefined) {
>foo3 : Symbol(foo3, Decl(logicalAssignment8.ts, 8, 1))
>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14))
(results &&= bar?.value ?? []).push(100);
>(results &&= bar?.value ?? []).push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>results : Symbol(results, Decl(logicalAssignment8.ts, 10, 14))
>bar?.value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>bar : Symbol(bar, Decl(logicalAssignment8.ts, 0, 13))
>value : Symbol(value, Decl(logicalAssignment8.ts, 0, 20))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
}

View File

@ -0,0 +1,61 @@
=== tests/cases/conformance/esnext/logicalAssignment/logicalAssignment8.ts ===
declare const bar: { value?: number[] } | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
function foo1(results: number[] | undefined) {
>foo1 : (results: number[] | undefined) => void
>results : number[] | undefined
(results ||= bar?.value ?? []).push(100);
>(results ||= bar?.value ?? []).push(100) : number
>(results ||= bar?.value ?? []).push : (...items: number[]) => number
>(results ||= bar?.value ?? []) : number[]
>results ||= bar?.value ?? [] : number[]
>results : number[] | undefined
>bar?.value ?? [] : number[]
>bar?.value : number[] | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
>[] : never[]
>push : (...items: number[]) => number
>100 : 100
}
function foo2(results: number[] | undefined) {
>foo2 : (results: number[] | undefined) => void
>results : number[] | undefined
(results ??= bar?.value ?? []).push(100);
>(results ??= bar?.value ?? []).push(100) : number
>(results ??= bar?.value ?? []).push : (...items: number[]) => number
>(results ??= bar?.value ?? []) : number[]
>results ??= bar?.value ?? [] : number[]
>results : number[] | undefined
>bar?.value ?? [] : number[]
>bar?.value : number[] | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
>[] : never[]
>push : (...items: number[]) => number
>100 : 100
}
function foo3(results: number[] | undefined) {
>foo3 : (results: number[] | undefined) => void
>results : number[] | undefined
(results &&= bar?.value ?? []).push(100);
>(results &&= bar?.value ?? []).push(100) : number
>(results &&= bar?.value ?? []).push : (...items: number[]) => number
>(results &&= bar?.value ?? []) : number[] | undefined
>results &&= bar?.value ?? [] : number[] | undefined
>results : number[] | undefined
>bar?.value ?? [] : number[]
>bar?.value : number[] | undefined
>bar : { value?: number[] | undefined; } | undefined
>value : number[] | undefined
>[] : never[]
>push : (...items: number[]) => number
>100 : 100
}

View File

@ -0,0 +1,16 @@
// @strict: true
// @target: esnext, es2020, es2015
declare const bar: { value?: number[] } | undefined
function foo1(results: number[] | undefined) {
(results ||= bar?.value ?? []).push(100);
}
function foo2(results: number[] | undefined) {
(results ??= bar?.value ?? []).push(100);
}
function foo3(results: number[] | undefined) {
(results &&= bar?.value ?? []).push(100);
}