From ee846d95af9d55280fc5cc97741403268ef9b242 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 19 Oct 2019 10:52:04 -0700 Subject: [PATCH] Accept new baselines --- .../controlFlowOptionalChain.errors.txt | 259 +++++++- .../reference/controlFlowOptionalChain.js | 376 +++++++++++ .../controlFlowOptionalChain.symbols | 572 ++++++++++++++++- .../reference/controlFlowOptionalChain.types | 599 ++++++++++++++++++ 4 files changed, 1786 insertions(+), 20 deletions(-) diff --git a/tests/baselines/reference/controlFlowOptionalChain.errors.txt b/tests/baselines/reference/controlFlowOptionalChain.errors.txt index 987dca335dc..ee77494d1c8 100644 --- a/tests/baselines/reference/controlFlowOptionalChain.errors.txt +++ b/tests/baselines/reference/controlFlowOptionalChain.errors.txt @@ -31,9 +31,29 @@ tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(244,9): error TS tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(271,9): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(274,9): error TS2532: Object is possibly 'undefined'. tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(277,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(307,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(310,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(319,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(322,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(331,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(340,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(343,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(352,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(391,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(394,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(403,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(406,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(415,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(424,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(427,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(436,9): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(471,13): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(474,13): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(488,13): error TS2532: Object is possibly 'undefined'. +tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(491,13): error TS2532: Object is possibly 'undefined'. -==== tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts (33 errors) ==== +==== tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts (53 errors) ==== // assignments in shortcutting chain declare const o: undefined | { [key: string]: any; @@ -401,6 +421,76 @@ tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(277,9): error TS } } + function f15(o: Thing | undefined, value: number) { + if (o?.foo === value) { + o.foo; + } + else { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + if (o?.foo !== value) { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + else { + o.foo; + } + if (o?.foo == value) { + o.foo; + } + else { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + if (o?.foo != value) { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + else { + o.foo; + } + } + + function f16(o: Thing | undefined) { + if (o?.foo === undefined) { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + else { + o.foo; + } + if (o?.foo !== undefined) { + o.foo; + } + else { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + if (o?.foo == undefined) { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + else { + o.foo; + } + if (o?.foo != undefined) { + o.foo; + } + else { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + } + function f20(o: Thing | undefined) { if (typeof o?.foo === "number") { o.foo; @@ -430,4 +520,171 @@ tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(277,9): error TS o.baz; } } + + function f22(o: Thing | undefined) { + if (typeof o?.foo === "number") { + o.foo; + } + else { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + if (typeof o?.foo !== "number") { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + else { + o.foo; + } + if (typeof o?.foo == "number") { + o.foo; + } + else { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + if (typeof o?.foo != "number") { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + else { + o.foo; + } + } + + function f23(o: Thing | undefined) { + if (typeof o?.foo === "undefined") { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + else { + o.foo; + } + if (typeof o?.foo !== "undefined") { + o.foo; + } + else { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + if (typeof o?.foo == "undefined") { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + else { + o.foo; + } + if (typeof o?.foo != "undefined") { + o.foo; + } + else { + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + } + } + + declare function assert(x: unknown): asserts x; + declare function assertNonNull(x: T): asserts x is NonNullable; + + function f30(o: Thing | undefined) { + if (!!true) { + assert(o?.foo); + o.foo; + } + if (!!true) { + assert(o?.foo === 42); + o.foo; + } + if (!!true) { + assert(typeof o?.foo === "number"); + o.foo; + } + if (!!true) { + assertNonNull(o?.foo); + o.foo; + } + } + + function f40(o: Thing | undefined) { + switch (o?.foo) { + case "abc": + o.foo; + break; + case 42: + o.foo; + break; + case undefined: + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + break; + default: + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + break; + } + } + + function f41(o: Thing | undefined) { + switch (typeof o?.foo) { + case "string": + o.foo; + break; + case "number": + o.foo; + break; + case "undefined": + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + break; + default: + o.foo; // Error + ~ +!!! error TS2532: Object is possibly 'undefined'. + break; + } + } + + // Repros from #34570 + + type Shape = + | { type: 'rectangle', width: number, height: number } + | { type: 'circle', radius: number } + + function getArea(shape?: Shape) { + switch (shape?.type) { + case 'circle': + return Math.PI * shape.radius ** 2 + case 'rectangle': + return shape.width * shape.height + default: + return 0 + } + } + + type Feature = { + id: string; + geometry?: { + type: string; + coordinates: number[]; + }; + }; + + + function extractCoordinates(f: Feature): number[] { + if (f.geometry?.type !== 'test') { + return []; + } + return f.geometry.coordinates; + } \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowOptionalChain.js b/tests/baselines/reference/controlFlowOptionalChain.js index 21451528035..3bb2bab1c0d 100644 --- a/tests/baselines/reference/controlFlowOptionalChain.js +++ b/tests/baselines/reference/controlFlowOptionalChain.js @@ -300,6 +300,60 @@ function f14(o: Thing | null) { } } +function f15(o: Thing | undefined, value: number) { + if (o?.foo === value) { + o.foo; + } + else { + o.foo; // Error + } + if (o?.foo !== value) { + o.foo; // Error + } + else { + o.foo; + } + if (o?.foo == value) { + o.foo; + } + else { + o.foo; // Error + } + if (o?.foo != value) { + o.foo; // Error + } + else { + o.foo; + } +} + +function f16(o: Thing | undefined) { + if (o?.foo === undefined) { + o.foo; // Error + } + else { + o.foo; + } + if (o?.foo !== undefined) { + o.foo; + } + else { + o.foo; // Error + } + if (o?.foo == undefined) { + o.foo; // Error + } + else { + o.foo; + } + if (o?.foo != undefined) { + o.foo; + } + else { + o.foo; // Error + } +} + function f20(o: Thing | undefined) { if (typeof o?.foo === "number") { o.foo; @@ -329,6 +383,149 @@ function f21(o: Thing | null) { o.baz; } } + +function f22(o: Thing | undefined) { + if (typeof o?.foo === "number") { + o.foo; + } + else { + o.foo; // Error + } + if (typeof o?.foo !== "number") { + o.foo; // Error + } + else { + o.foo; + } + if (typeof o?.foo == "number") { + o.foo; + } + else { + o.foo; // Error + } + if (typeof o?.foo != "number") { + o.foo; // Error + } + else { + o.foo; + } +} + +function f23(o: Thing | undefined) { + if (typeof o?.foo === "undefined") { + o.foo; // Error + } + else { + o.foo; + } + if (typeof o?.foo !== "undefined") { + o.foo; + } + else { + o.foo; // Error + } + if (typeof o?.foo == "undefined") { + o.foo; // Error + } + else { + o.foo; + } + if (typeof o?.foo != "undefined") { + o.foo; + } + else { + o.foo; // Error + } +} + +declare function assert(x: unknown): asserts x; +declare function assertNonNull(x: T): asserts x is NonNullable; + +function f30(o: Thing | undefined) { + if (!!true) { + assert(o?.foo); + o.foo; + } + if (!!true) { + assert(o?.foo === 42); + o.foo; + } + if (!!true) { + assert(typeof o?.foo === "number"); + o.foo; + } + if (!!true) { + assertNonNull(o?.foo); + o.foo; + } +} + +function f40(o: Thing | undefined) { + switch (o?.foo) { + case "abc": + o.foo; + break; + case 42: + o.foo; + break; + case undefined: + o.foo; // Error + break; + default: + o.foo; // Error + break; + } +} + +function f41(o: Thing | undefined) { + switch (typeof o?.foo) { + case "string": + o.foo; + break; + case "number": + o.foo; + break; + case "undefined": + o.foo; // Error + break; + default: + o.foo; // Error + break; + } +} + +// Repros from #34570 + +type Shape = + | { type: 'rectangle', width: number, height: number } + | { type: 'circle', radius: number } + +function getArea(shape?: Shape) { + switch (shape?.type) { + case 'circle': + return Math.PI * shape.radius ** 2 + case 'rectangle': + return shape.width * shape.height + default: + return 0 + } +} + +type Feature = { + id: string; + geometry?: { + type: string; + coordinates: number[]; + }; +}; + + +function extractCoordinates(f: Feature): number[] { + if (f.geometry?.type !== 'test') { + return []; + } + return f.geometry.coordinates; +} //// [controlFlowOptionalChain.js] @@ -594,6 +791,60 @@ function f14(o) { o.bar; } } +function f15(o, value) { + var _a, _b, _c, _d; + if (((_a = o) === null || _a === void 0 ? void 0 : _a.foo) === value) { + o.foo; + } + else { + o.foo; // Error + } + if (((_b = o) === null || _b === void 0 ? void 0 : _b.foo) !== value) { + o.foo; // Error + } + else { + o.foo; + } + if (((_c = o) === null || _c === void 0 ? void 0 : _c.foo) == value) { + o.foo; + } + else { + o.foo; // Error + } + if (((_d = o) === null || _d === void 0 ? void 0 : _d.foo) != value) { + o.foo; // Error + } + else { + o.foo; + } +} +function f16(o) { + var _a, _b, _c, _d; + if (((_a = o) === null || _a === void 0 ? void 0 : _a.foo) === undefined) { + o.foo; // Error + } + else { + o.foo; + } + if (((_b = o) === null || _b === void 0 ? void 0 : _b.foo) !== undefined) { + o.foo; + } + else { + o.foo; // Error + } + if (((_c = o) === null || _c === void 0 ? void 0 : _c.foo) == undefined) { + o.foo; // Error + } + else { + o.foo; + } + if (((_d = o) === null || _d === void 0 ? void 0 : _d.foo) != undefined) { + o.foo; + } + else { + o.foo; // Error + } +} function f20(o) { var _a, _b, _c, _d; if (typeof ((_a = o) === null || _a === void 0 ? void 0 : _a.foo) === "number") { @@ -624,3 +875,128 @@ function f21(o) { o.baz; } } +function f22(o) { + var _a, _b, _c, _d; + if (typeof ((_a = o) === null || _a === void 0 ? void 0 : _a.foo) === "number") { + o.foo; + } + else { + o.foo; // Error + } + if (typeof ((_b = o) === null || _b === void 0 ? void 0 : _b.foo) !== "number") { + o.foo; // Error + } + else { + o.foo; + } + if (typeof ((_c = o) === null || _c === void 0 ? void 0 : _c.foo) == "number") { + o.foo; + } + else { + o.foo; // Error + } + if (typeof ((_d = o) === null || _d === void 0 ? void 0 : _d.foo) != "number") { + o.foo; // Error + } + else { + o.foo; + } +} +function f23(o) { + var _a, _b, _c, _d; + if (typeof ((_a = o) === null || _a === void 0 ? void 0 : _a.foo) === "undefined") { + o.foo; // Error + } + else { + o.foo; + } + if (typeof ((_b = o) === null || _b === void 0 ? void 0 : _b.foo) !== "undefined") { + o.foo; + } + else { + o.foo; // Error + } + if (typeof ((_c = o) === null || _c === void 0 ? void 0 : _c.foo) == "undefined") { + o.foo; // Error + } + else { + o.foo; + } + if (typeof ((_d = o) === null || _d === void 0 ? void 0 : _d.foo) != "undefined") { + o.foo; + } + else { + o.foo; // Error + } +} +function f30(o) { + var _a, _b, _c, _d; + if (!!true) { + assert((_a = o) === null || _a === void 0 ? void 0 : _a.foo); + o.foo; + } + if (!!true) { + assert(((_b = o) === null || _b === void 0 ? void 0 : _b.foo) === 42); + o.foo; + } + if (!!true) { + assert(typeof ((_c = o) === null || _c === void 0 ? void 0 : _c.foo) === "number"); + o.foo; + } + if (!!true) { + assertNonNull((_d = o) === null || _d === void 0 ? void 0 : _d.foo); + o.foo; + } +} +function f40(o) { + var _a; + switch ((_a = o) === null || _a === void 0 ? void 0 : _a.foo) { + case "abc": + o.foo; + break; + case 42: + o.foo; + break; + case undefined: + o.foo; // Error + break; + default: + o.foo; // Error + break; + } +} +function f41(o) { + var _a; + switch (typeof ((_a = o) === null || _a === void 0 ? void 0 : _a.foo)) { + case "string": + o.foo; + break; + case "number": + o.foo; + break; + case "undefined": + o.foo; // Error + break; + default: + o.foo; // Error + break; + } +} +function getArea(shape) { + var _a; + switch ((_a = shape) === null || _a === void 0 ? void 0 : _a.type) { + case 'circle': + return Math.PI * Math.pow(shape.radius, 2); + case 'rectangle': + return shape.width * shape.height; + default: + return 0; + } +} +function extractCoordinates(f) { + var _a; + if (((_a = f.geometry) === null || _a === void 0 ? void 0 : _a.type) !== 'test') { + return []; + } + return f.geometry.coordinates; +} diff --git a/tests/baselines/reference/controlFlowOptionalChain.symbols b/tests/baselines/reference/controlFlowOptionalChain.symbols index 2665a960a56..cac0899cc89 100644 --- a/tests/baselines/reference/controlFlowOptionalChain.symbols +++ b/tests/baselines/reference/controlFlowOptionalChain.symbols @@ -1039,93 +1039,627 @@ function f14(o: Thing | null) { } } -function f20(o: Thing | undefined) { ->f20 : Symbol(f20, Decl(controlFlowOptionalChain.ts, 299, 1)) +function f15(o: Thing | undefined, value: number) { +>f15 : Symbol(f15, Decl(controlFlowOptionalChain.ts, 299, 1)) >o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) >Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1)) +>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 301, 34)) - if (typeof o?.foo === "number") { + if (o?.foo === value) { >o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) >o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) >foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 301, 34)) o.foo; >o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) >o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) >foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) } - if (typeof o?.["foo"] === "number") { + else { + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) >o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (o?.foo !== value) { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 301, 34)) + + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (o?.foo == value) { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 301, 34)) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (o?.foo != value) { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 301, 34)) + + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } +} + +function f16(o: Thing | undefined) { +>f16 : Symbol(f16, Decl(controlFlowOptionalChain.ts, 326, 1)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1)) + + if (o?.foo === undefined) { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>undefined : Symbol(undefined) + + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (o?.foo !== undefined) { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>undefined : Symbol(undefined) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (o?.foo == undefined) { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>undefined : Symbol(undefined) + + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (o?.foo != undefined) { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>undefined : Symbol(undefined) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } +} + +function f20(o: Thing | undefined) { +>f20 : Symbol(f20, Decl(controlFlowOptionalChain.ts, 353, 1)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13)) +>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1)) + + if (typeof o?.foo === "number") { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (typeof o?.["foo"] === "number") { +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13)) o["foo"]; ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13)) >"foo" : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) } if (typeof o?.bar() === "number") { >o?.bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13)) >bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36)) o.bar; >o.bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13)) >bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36)) } if (o?.baz instanceof Error) { >o?.baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13)) >baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) o.baz; >o.baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13)) >baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51)) } } function f21(o: Thing | null) { ->f21 : Symbol(f21, Decl(controlFlowOptionalChain.ts, 314, 1)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13)) +>f21 : Symbol(f21, Decl(controlFlowOptionalChain.ts, 368, 1)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13)) >Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1)) if (typeof o?.foo === "number") { >o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13)) >foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) o.foo; >o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13)) >foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) } if (typeof o?.["foo"] === "number") { ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13)) o["foo"]; ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13)) >"foo" : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) } if (typeof o?.bar() === "number") { >o?.bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13)) >bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36)) o.bar; >o.bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13)) >bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36)) } if (o?.baz instanceof Error) { >o?.baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13)) >baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) o.baz; >o.baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51)) ->o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13)) >baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51)) } } +function f22(o: Thing | undefined) { +>f22 : Symbol(f22, Decl(controlFlowOptionalChain.ts, 383, 1)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1)) + + if (typeof o?.foo === "number") { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (typeof o?.foo !== "number") { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (typeof o?.foo == "number") { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (typeof o?.foo != "number") { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } +} + +function f23(o: Thing | undefined) { +>f23 : Symbol(f23, Decl(controlFlowOptionalChain.ts, 410, 1)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1)) + + if (typeof o?.foo === "undefined") { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (typeof o?.foo !== "undefined") { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (typeof o?.foo == "undefined") { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (typeof o?.foo != "undefined") { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + else { + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } +} + +declare function assert(x: unknown): asserts x; +>assert : Symbol(assert, Decl(controlFlowOptionalChain.ts, 437, 1)) +>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 439, 24)) +>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 439, 24)) + +declare function assertNonNull(x: T): asserts x is NonNullable; +>assertNonNull : Symbol(assertNonNull, Decl(controlFlowOptionalChain.ts, 439, 47)) +>T : Symbol(T, Decl(controlFlowOptionalChain.ts, 440, 31)) +>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 440, 34)) +>T : Symbol(T, Decl(controlFlowOptionalChain.ts, 440, 31)) +>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 440, 34)) +>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(controlFlowOptionalChain.ts, 440, 31)) + +function f30(o: Thing | undefined) { +>f30 : Symbol(f30, Decl(controlFlowOptionalChain.ts, 440, 69)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13)) +>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1)) + + if (!!true) { + assert(o?.foo); +>assert : Symbol(assert, Decl(controlFlowOptionalChain.ts, 437, 1)) +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (!!true) { + assert(o?.foo === 42); +>assert : Symbol(assert, Decl(controlFlowOptionalChain.ts, 437, 1)) +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (!!true) { + assert(typeof o?.foo === "number"); +>assert : Symbol(assert, Decl(controlFlowOptionalChain.ts, 437, 1)) +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } + if (!!true) { + assertNonNull(o?.foo); +>assertNonNull : Symbol(assertNonNull, Decl(controlFlowOptionalChain.ts, 439, 47)) +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + } +} + +function f40(o: Thing | undefined) { +>f40 : Symbol(f40, Decl(controlFlowOptionalChain.ts, 459, 1)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13)) +>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1)) + + switch (o?.foo) { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + case "abc": + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + break; + case 42: + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + break; + case undefined: +>undefined : Symbol(undefined) + + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + break; + default: + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + break; + } +} + +function f41(o: Thing | undefined) { +>f41 : Symbol(f41, Decl(controlFlowOptionalChain.ts, 476, 1)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13)) +>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1)) + + switch (typeof o?.foo) { +>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + case "string": + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + break; + case "number": + o.foo; +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + break; + case "undefined": + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + break; + default: + o.foo; // Error +>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) +>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13)) +>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14)) + + break; + } +} + +// Repros from #34570 + +type Shape = +>Shape : Symbol(Shape, Decl(controlFlowOptionalChain.ts, 493, 1)) + + | { type: 'rectangle', width: number, height: number } +>type : Symbol(type, Decl(controlFlowOptionalChain.ts, 498, 7)) +>width : Symbol(width, Decl(controlFlowOptionalChain.ts, 498, 26)) +>height : Symbol(height, Decl(controlFlowOptionalChain.ts, 498, 41)) + + | { type: 'circle', radius: number } +>type : Symbol(type, Decl(controlFlowOptionalChain.ts, 499, 7)) +>radius : Symbol(radius, Decl(controlFlowOptionalChain.ts, 499, 23)) + +function getArea(shape?: Shape) { +>getArea : Symbol(getArea, Decl(controlFlowOptionalChain.ts, 499, 40)) +>shape : Symbol(shape, Decl(controlFlowOptionalChain.ts, 501, 17)) +>Shape : Symbol(Shape, Decl(controlFlowOptionalChain.ts, 493, 1)) + + switch (shape?.type) { +>shape?.type : Symbol(type, Decl(controlFlowOptionalChain.ts, 498, 7), Decl(controlFlowOptionalChain.ts, 499, 7)) +>shape : Symbol(shape, Decl(controlFlowOptionalChain.ts, 501, 17)) +>type : Symbol(type, Decl(controlFlowOptionalChain.ts, 498, 7), Decl(controlFlowOptionalChain.ts, 499, 7)) + + case 'circle': + return Math.PI * shape.radius ** 2 +>Math.PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --)) +>shape.radius : Symbol(radius, Decl(controlFlowOptionalChain.ts, 499, 23)) +>shape : Symbol(shape, Decl(controlFlowOptionalChain.ts, 501, 17)) +>radius : Symbol(radius, Decl(controlFlowOptionalChain.ts, 499, 23)) + + case 'rectangle': + return shape.width * shape.height +>shape.width : Symbol(width, Decl(controlFlowOptionalChain.ts, 498, 26)) +>shape : Symbol(shape, Decl(controlFlowOptionalChain.ts, 501, 17)) +>width : Symbol(width, Decl(controlFlowOptionalChain.ts, 498, 26)) +>shape.height : Symbol(height, Decl(controlFlowOptionalChain.ts, 498, 41)) +>shape : Symbol(shape, Decl(controlFlowOptionalChain.ts, 501, 17)) +>height : Symbol(height, Decl(controlFlowOptionalChain.ts, 498, 41)) + + default: + return 0 + } +} + +type Feature = { +>Feature : Symbol(Feature, Decl(controlFlowOptionalChain.ts, 510, 1)) + + id: string; +>id : Symbol(id, Decl(controlFlowOptionalChain.ts, 512, 16)) + + geometry?: { +>geometry : Symbol(geometry, Decl(controlFlowOptionalChain.ts, 513, 13)) + + type: string; +>type : Symbol(type, Decl(controlFlowOptionalChain.ts, 514, 14)) + + coordinates: number[]; +>coordinates : Symbol(coordinates, Decl(controlFlowOptionalChain.ts, 515, 17)) + + }; +}; + + +function extractCoordinates(f: Feature): number[] { +>extractCoordinates : Symbol(extractCoordinates, Decl(controlFlowOptionalChain.ts, 518, 2)) +>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 521, 28)) +>Feature : Symbol(Feature, Decl(controlFlowOptionalChain.ts, 510, 1)) + + if (f.geometry?.type !== 'test') { +>f.geometry?.type : Symbol(type, Decl(controlFlowOptionalChain.ts, 514, 14)) +>f.geometry : Symbol(geometry, Decl(controlFlowOptionalChain.ts, 513, 13)) +>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 521, 28)) +>geometry : Symbol(geometry, Decl(controlFlowOptionalChain.ts, 513, 13)) +>type : Symbol(type, Decl(controlFlowOptionalChain.ts, 514, 14)) + + return []; + } + return f.geometry.coordinates; +>f.geometry.coordinates : Symbol(coordinates, Decl(controlFlowOptionalChain.ts, 515, 17)) +>f.geometry : Symbol(geometry, Decl(controlFlowOptionalChain.ts, 513, 13)) +>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 521, 28)) +>geometry : Symbol(geometry, Decl(controlFlowOptionalChain.ts, 513, 13)) +>coordinates : Symbol(coordinates, Decl(controlFlowOptionalChain.ts, 515, 17)) +} + diff --git a/tests/baselines/reference/controlFlowOptionalChain.types b/tests/baselines/reference/controlFlowOptionalChain.types index ffec7d1525e..13dd6cd5fd0 100644 --- a/tests/baselines/reference/controlFlowOptionalChain.types +++ b/tests/baselines/reference/controlFlowOptionalChain.types @@ -1170,6 +1170,163 @@ function f14(o: Thing | null) { } } +function f15(o: Thing | undefined, value: number) { +>f15 : (o: Thing | undefined, value: number) => void +>o : Thing | undefined +>value : number + + if (o?.foo === value) { +>o?.foo === value : boolean +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>value : number + + o.foo; +>o.foo : number +>o : Thing +>foo : number + } + else { + o.foo; // Error +>o.foo : string | number +>o : Thing | undefined +>foo : string | number + } + if (o?.foo !== value) { +>o?.foo !== value : boolean +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>value : number + + o.foo; // Error +>o.foo : string | number +>o : Thing | undefined +>foo : string | number + } + else { + o.foo; +>o.foo : number +>o : Thing +>foo : number + } + if (o?.foo == value) { +>o?.foo == value : boolean +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>value : number + + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } + else { + o.foo; // Error +>o.foo : string | number +>o : Thing | undefined +>foo : string | number + } + if (o?.foo != value) { +>o?.foo != value : boolean +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>value : number + + o.foo; // Error +>o.foo : string | number +>o : Thing | undefined +>foo : string | number + } + else { + o.foo; +>o.foo : number +>o : Thing +>foo : number + } +} + +function f16(o: Thing | undefined) { +>f16 : (o: Thing | undefined) => void +>o : Thing | undefined + + if (o?.foo === undefined) { +>o?.foo === undefined : boolean +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>undefined : undefined + + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + } + else { + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } + if (o?.foo !== undefined) { +>o?.foo !== undefined : boolean +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>undefined : undefined + + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } + else { + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + } + if (o?.foo == undefined) { +>o?.foo == undefined : boolean +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>undefined : undefined + + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + } + else { + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } + if (o?.foo != undefined) { +>o?.foo != undefined : boolean +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>undefined : undefined + + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } + else { + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + } +} + function f20(o: Thing | undefined) { >f20 : (o: Thing | undefined) => void >o : Thing | undefined @@ -1287,3 +1444,445 @@ function f21(o: Thing | null) { } } +function f22(o: Thing | undefined) { +>f22 : (o: Thing | undefined) => void +>o : Thing | undefined + + if (typeof o?.foo === "number") { +>typeof o?.foo === "number" : boolean +>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>"number" : "number" + + o.foo; +>o.foo : number +>o : Thing +>foo : number + } + else { + o.foo; // Error +>o.foo : string +>o : Thing | undefined +>foo : string + } + if (typeof o?.foo !== "number") { +>typeof o?.foo !== "number" : boolean +>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>"number" : "number" + + o.foo; // Error +>o.foo : string +>o : Thing | undefined +>foo : string + } + else { + o.foo; +>o.foo : number +>o : Thing +>foo : number + } + if (typeof o?.foo == "number") { +>typeof o?.foo == "number" : boolean +>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>"number" : "number" + + o.foo; +>o.foo : number +>o : Thing +>foo : number + } + else { + o.foo; // Error +>o.foo : string +>o : Thing | undefined +>foo : string + } + if (typeof o?.foo != "number") { +>typeof o?.foo != "number" : boolean +>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>"number" : "number" + + o.foo; // Error +>o.foo : string +>o : Thing | undefined +>foo : string + } + else { + o.foo; +>o.foo : number +>o : Thing +>foo : number + } +} + +function f23(o: Thing | undefined) { +>f23 : (o: Thing | undefined) => void +>o : Thing | undefined + + if (typeof o?.foo === "undefined") { +>typeof o?.foo === "undefined" : boolean +>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>"undefined" : "undefined" + + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + } + else { + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } + if (typeof o?.foo !== "undefined") { +>typeof o?.foo !== "undefined" : boolean +>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>"undefined" : "undefined" + + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } + else { + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + } + if (typeof o?.foo == "undefined") { +>typeof o?.foo == "undefined" : boolean +>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>"undefined" : "undefined" + + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + } + else { + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } + if (typeof o?.foo != "undefined") { +>typeof o?.foo != "undefined" : boolean +>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>"undefined" : "undefined" + + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } + else { + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + } +} + +declare function assert(x: unknown): asserts x; +>assert : (x: unknown) => asserts x +>x : unknown + +declare function assertNonNull(x: T): asserts x is NonNullable; +>assertNonNull : (x: T) => asserts x is NonNullable +>x : T + +function f30(o: Thing | undefined) { +>f30 : (o: Thing | undefined) => void +>o : Thing | undefined + + if (!!true) { +>!!true : true +>!true : false +>true : true + + assert(o?.foo); +>assert(o?.foo) : void +>assert : (x: unknown) => asserts x +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined + + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + assert(o?.foo === 42); +>assert(o?.foo === 42) : void +>assert : (x: unknown) => asserts x +>o?.foo === 42 : boolean +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>42 : 42 + + o.foo; +>o.foo : 42 +>o : Thing +>foo : 42 + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + assert(typeof o?.foo === "number"); +>assert(typeof o?.foo === "number") : void +>assert : (x: unknown) => asserts x +>typeof o?.foo === "number" : boolean +>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined +>"number" : "number" + + o.foo; +>o.foo : number +>o : Thing +>foo : number + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + assertNonNull(o?.foo); +>assertNonNull(o?.foo) : void +>assertNonNull : (x: T) => asserts x is NonNullable +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined + + o.foo; +>o.foo : string | number +>o : Thing +>foo : string | number + } +} + +function f40(o: Thing | undefined) { +>f40 : (o: Thing | undefined) => void +>o : Thing | undefined + + switch (o?.foo) { +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined + + case "abc": +>"abc" : "abc" + + o.foo; +>o.foo : "abc" +>o : Thing +>foo : "abc" + + break; + case 42: +>42 : 42 + + o.foo; +>o.foo : 42 +>o : Thing +>foo : 42 + + break; + case undefined: +>undefined : undefined + + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + + break; + default: + o.foo; // Error +>o.foo : string | number +>o : Thing | undefined +>foo : string | number + + break; + } +} + +function f41(o: Thing | undefined) { +>f41 : (o: Thing | undefined) => void +>o : Thing | undefined + + switch (typeof o?.foo) { +>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>o?.foo : string | number | undefined +>o : Thing | undefined +>foo : string | number | undefined + + case "string": +>"string" : "string" + + o.foo; +>o.foo : string +>o : Thing +>foo : string + + break; + case "number": +>"number" : "number" + + o.foo; +>o.foo : number +>o : Thing +>foo : number + + break; + case "undefined": +>"undefined" : "undefined" + + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + + break; + default: + o.foo; // Error +>o.foo : never +>o : Thing | undefined +>foo : never + + break; + } +} + +// Repros from #34570 + +type Shape = +>Shape : Shape + + | { type: 'rectangle', width: number, height: number } +>type : "rectangle" +>width : number +>height : number + + | { type: 'circle', radius: number } +>type : "circle" +>radius : number + +function getArea(shape?: Shape) { +>getArea : (shape?: { type: "rectangle"; width: number; height: number; } | { type: "circle"; radius: number; } | undefined) => number +>shape : { type: "rectangle"; width: number; height: number; } | { type: "circle"; radius: number; } | undefined + + switch (shape?.type) { +>shape?.type : "rectangle" | "circle" | undefined +>shape : { type: "rectangle"; width: number; height: number; } | { type: "circle"; radius: number; } | undefined +>type : "rectangle" | "circle" | undefined + + case 'circle': +>'circle' : "circle" + + return Math.PI * shape.radius ** 2 +>Math.PI * shape.radius ** 2 : number +>Math.PI : number +>Math : Math +>PI : number +>shape.radius ** 2 : number +>shape.radius : number +>shape : { type: "circle"; radius: number; } +>radius : number +>2 : 2 + + case 'rectangle': +>'rectangle' : "rectangle" + + return shape.width * shape.height +>shape.width * shape.height : number +>shape.width : number +>shape : { type: "rectangle"; width: number; height: number; } +>width : number +>shape.height : number +>shape : { type: "rectangle"; width: number; height: number; } +>height : number + + default: + return 0 +>0 : 0 + } +} + +type Feature = { +>Feature : Feature + + id: string; +>id : string + + geometry?: { +>geometry : { type: string; coordinates: number[]; } | undefined + + type: string; +>type : string + + coordinates: number[]; +>coordinates : number[] + + }; +}; + + +function extractCoordinates(f: Feature): number[] { +>extractCoordinates : (f: Feature) => number[] +>f : Feature + + if (f.geometry?.type !== 'test') { +>f.geometry?.type !== 'test' : boolean +>f.geometry?.type : string | undefined +>f.geometry : { type: string; coordinates: number[]; } | undefined +>f : Feature +>geometry : { type: string; coordinates: number[]; } | undefined +>type : string | undefined +>'test' : "test" + + return []; +>[] : never[] + } + return f.geometry.coordinates; +>f.geometry.coordinates : number[] +>f.geometry : { type: string; coordinates: number[]; } +>f : Feature +>geometry : { type: string; coordinates: number[]; } +>coordinates : number[] +} +