From 9a31f61b8759e2139f9b30595a6a9202083a16ee Mon Sep 17 00:00:00 2001 From: Gabriela Araujo Britto Date: Tue, 12 Mar 2024 11:50:58 -0700 Subject: [PATCH] add and fix tests --- ...iminantNarrowingCouldBeCircular.errors.txt | 52 +++++++ .../discriminantNarrowingCouldBeCircular.js | 68 +++++++++ ...scriminantNarrowingCouldBeCircular.symbols | 121 ++++++++++++++++ ...discriminantNarrowingCouldBeCircular.types | 134 ++++++++++++++++++ ...ImportHelpersCollisions3(module=node16).js | 2 +- ...portHelpersCollisions3(module=nodenext).js | 2 +- ...ePredicatesCanNarrowByDiscriminant.symbols | 8 +- ...ypePredicatesCanNarrowByDiscriminant.types | 12 +- .../discriminantNarrowingCouldBeCircular.ts | 39 +++++ 9 files changed, 426 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/discriminantNarrowingCouldBeCircular.errors.txt create mode 100644 tests/baselines/reference/discriminantNarrowingCouldBeCircular.js create mode 100644 tests/baselines/reference/discriminantNarrowingCouldBeCircular.symbols create mode 100644 tests/baselines/reference/discriminantNarrowingCouldBeCircular.types create mode 100644 tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts diff --git a/tests/baselines/reference/discriminantNarrowingCouldBeCircular.errors.txt b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.errors.txt new file mode 100644 index 0000000000000..53f9684e13ebe --- /dev/null +++ b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.errors.txt @@ -0,0 +1,52 @@ +discriminantNarrowingCouldBeCircular.ts(13,53): error TS2304: Cannot find name 'Element'. +discriminantNarrowingCouldBeCircular.ts(13,63): error TS2304: Cannot find name 'Element'. +discriminantNarrowingCouldBeCircular.ts(15,39): error TS2304: Cannot find name 'Element'. +discriminantNarrowingCouldBeCircular.ts(16,17): error TS2304: Cannot find name 'Element'. + + +==== discriminantNarrowingCouldBeCircular.ts (4 errors) ==== + // #57705, 57690 + declare function is(v: T): v is T; + const o: Record | undefined = {}; + if (o) { + for (const key in o) { + const value = o[key]; + if (is(value)) { + } + } + } + + declare const kPresentationInheritanceParents: { [tagName: string]: string[] }; + declare function parentElementOrShadowHost(element: Element): Element | undefined; + ~~~~~~~ +!!! error TS2304: Cannot find name 'Element'. + ~~~~~~~ +!!! error TS2304: Cannot find name 'Element'. + + function getImplicitAriaRole(element: Element) { + ~~~~~~~ +!!! error TS2304: Cannot find name 'Element'. + let ancestor: Element | null = element; + ~~~~~~~ +!!! error TS2304: Cannot find name 'Element'. + while (ancestor) { + const parent = parentElementOrShadowHost(ancestor); + const parents = kPresentationInheritanceParents[ancestor.tagName]; + if (!parents || !parent || !parents.includes(parent.tagName)) + break; + ancestor = parent; + } + } + + declare function isPlainObject2( + data: unknown, + ): data is Record; + + declare const myObj2: unknown; + if (isPlainObject2(myObj2)) { + for (const key of ["a", "b", "c"]) { + const deeper = myObj2[key]; + const deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/discriminantNarrowingCouldBeCircular.js b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.js new file mode 100644 index 0000000000000..2dc361a01254e --- /dev/null +++ b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.js @@ -0,0 +1,68 @@ +//// [tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts] //// + +//// [discriminantNarrowingCouldBeCircular.ts] +// #57705, 57690 +declare function is(v: T): v is T; +const o: Record | undefined = {}; +if (o) { + for (const key in o) { + const value = o[key]; + if (is(value)) { + } + } +} + +declare const kPresentationInheritanceParents: { [tagName: string]: string[] }; +declare function parentElementOrShadowHost(element: Element): Element | undefined; + +function getImplicitAriaRole(element: Element) { + let ancestor: Element | null = element; + while (ancestor) { + const parent = parentElementOrShadowHost(ancestor); + const parents = kPresentationInheritanceParents[ancestor.tagName]; + if (!parents || !parent || !parents.includes(parent.tagName)) + break; + ancestor = parent; + } +} + +declare function isPlainObject2( + data: unknown, + ): data is Record; + + declare const myObj2: unknown; + if (isPlainObject2(myObj2)) { + for (const key of ["a", "b", "c"]) { + const deeper = myObj2[key]; + const deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; + } + } + + +//// [discriminantNarrowingCouldBeCircular.js] +"use strict"; +var o = {}; +if (o) { + for (var key in o) { + var value = o[key]; + if (is(value)) { + } + } +} +function getImplicitAriaRole(element) { + var ancestor = element; + while (ancestor) { + var parent = parentElementOrShadowHost(ancestor); + var parents = kPresentationInheritanceParents[ancestor.tagName]; + if (!parents || !parent || !parents.includes(parent.tagName)) + break; + ancestor = parent; + } +} +if (isPlainObject2(myObj2)) { + for (var _i = 0, _a = ["a", "b", "c"]; _i < _a.length; _i++) { + var key = _a[_i]; + var deeper = myObj2[key]; + var deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; + } +} diff --git a/tests/baselines/reference/discriminantNarrowingCouldBeCircular.symbols b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.symbols new file mode 100644 index 0000000000000..083c29784d111 --- /dev/null +++ b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.symbols @@ -0,0 +1,121 @@ +//// [tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts] //// + +=== discriminantNarrowingCouldBeCircular.ts === +// #57705, 57690 +declare function is(v: T): v is T; +>is : Symbol(is, Decl(discriminantNarrowingCouldBeCircular.ts, 0, 0)) +>T : Symbol(T, Decl(discriminantNarrowingCouldBeCircular.ts, 1, 20)) +>v : Symbol(v, Decl(discriminantNarrowingCouldBeCircular.ts, 1, 23)) +>T : Symbol(T, Decl(discriminantNarrowingCouldBeCircular.ts, 1, 20)) +>v : Symbol(v, Decl(discriminantNarrowingCouldBeCircular.ts, 1, 23)) +>T : Symbol(T, Decl(discriminantNarrowingCouldBeCircular.ts, 1, 20)) + +const o: Record | undefined = {}; +>o : Symbol(o, Decl(discriminantNarrowingCouldBeCircular.ts, 2, 5)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + +if (o) { +>o : Symbol(o, Decl(discriminantNarrowingCouldBeCircular.ts, 2, 5)) + + for (const key in o) { +>key : Symbol(key, Decl(discriminantNarrowingCouldBeCircular.ts, 4, 12)) +>o : Symbol(o, Decl(discriminantNarrowingCouldBeCircular.ts, 2, 5)) + + const value = o[key]; +>value : Symbol(value, Decl(discriminantNarrowingCouldBeCircular.ts, 5, 9)) +>o : Symbol(o, Decl(discriminantNarrowingCouldBeCircular.ts, 2, 5)) +>key : Symbol(key, Decl(discriminantNarrowingCouldBeCircular.ts, 4, 12)) + + if (is(value)) { +>is : Symbol(is, Decl(discriminantNarrowingCouldBeCircular.ts, 0, 0)) +>value : Symbol(value, Decl(discriminantNarrowingCouldBeCircular.ts, 5, 9)) + } + } +} + +declare const kPresentationInheritanceParents: { [tagName: string]: string[] }; +>kPresentationInheritanceParents : Symbol(kPresentationInheritanceParents, Decl(discriminantNarrowingCouldBeCircular.ts, 11, 13)) +>tagName : Symbol(tagName, Decl(discriminantNarrowingCouldBeCircular.ts, 11, 50)) + +declare function parentElementOrShadowHost(element: Element): Element | undefined; +>parentElementOrShadowHost : Symbol(parentElementOrShadowHost, Decl(discriminantNarrowingCouldBeCircular.ts, 11, 79)) +>element : Symbol(element, Decl(discriminantNarrowingCouldBeCircular.ts, 12, 43)) +>Element : Symbol(Element) +>Element : Symbol(Element) + +function getImplicitAriaRole(element: Element) { +>getImplicitAriaRole : Symbol(getImplicitAriaRole, Decl(discriminantNarrowingCouldBeCircular.ts, 12, 82)) +>element : Symbol(element, Decl(discriminantNarrowingCouldBeCircular.ts, 14, 29)) +>Element : Symbol(Element) + + let ancestor: Element | null = element; +>ancestor : Symbol(ancestor, Decl(discriminantNarrowingCouldBeCircular.ts, 15, 5)) +>Element : Symbol(Element) +>element : Symbol(element, Decl(discriminantNarrowingCouldBeCircular.ts, 14, 29)) + + while (ancestor) { +>ancestor : Symbol(ancestor, Decl(discriminantNarrowingCouldBeCircular.ts, 15, 5)) + + const parent = parentElementOrShadowHost(ancestor); +>parent : Symbol(parent, Decl(discriminantNarrowingCouldBeCircular.ts, 17, 9)) +>parentElementOrShadowHost : Symbol(parentElementOrShadowHost, Decl(discriminantNarrowingCouldBeCircular.ts, 11, 79)) +>ancestor : Symbol(ancestor, Decl(discriminantNarrowingCouldBeCircular.ts, 15, 5)) + + const parents = kPresentationInheritanceParents[ancestor.tagName]; +>parents : Symbol(parents, Decl(discriminantNarrowingCouldBeCircular.ts, 18, 9)) +>kPresentationInheritanceParents : Symbol(kPresentationInheritanceParents, Decl(discriminantNarrowingCouldBeCircular.ts, 11, 13)) +>ancestor : Symbol(ancestor, Decl(discriminantNarrowingCouldBeCircular.ts, 15, 5)) + + if (!parents || !parent || !parents.includes(parent.tagName)) +>parents : Symbol(parents, Decl(discriminantNarrowingCouldBeCircular.ts, 18, 9)) +>parent : Symbol(parent, Decl(discriminantNarrowingCouldBeCircular.ts, 17, 9)) +>parents.includes : Symbol(Array.includes, Decl(lib.es2016.array.include.d.ts, --, --)) +>parents : Symbol(parents, Decl(discriminantNarrowingCouldBeCircular.ts, 18, 9)) +>includes : Symbol(Array.includes, Decl(lib.es2016.array.include.d.ts, --, --)) +>parent : Symbol(parent, Decl(discriminantNarrowingCouldBeCircular.ts, 17, 9)) + + break; + ancestor = parent; +>ancestor : Symbol(ancestor, Decl(discriminantNarrowingCouldBeCircular.ts, 15, 5)) +>parent : Symbol(parent, Decl(discriminantNarrowingCouldBeCircular.ts, 17, 9)) + } +} + +declare function isPlainObject2( +>isPlainObject2 : Symbol(isPlainObject2, Decl(discriminantNarrowingCouldBeCircular.ts, 23, 1)) +>T : Symbol(T, Decl(discriminantNarrowingCouldBeCircular.ts, 25, 32)) + + data: unknown, +>data : Symbol(data, Decl(discriminantNarrowingCouldBeCircular.ts, 25, 35)) + + ): data is Record; +>data : Symbol(data, Decl(discriminantNarrowingCouldBeCircular.ts, 25, 35)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>PropertyKey : Symbol(PropertyKey, Decl(lib.es5.d.ts, --, --)) + + declare const myObj2: unknown; +>myObj2 : Symbol(myObj2, Decl(discriminantNarrowingCouldBeCircular.ts, 29, 15)) + + if (isPlainObject2(myObj2)) { +>isPlainObject2 : Symbol(isPlainObject2, Decl(discriminantNarrowingCouldBeCircular.ts, 23, 1)) +>myObj2 : Symbol(myObj2, Decl(discriminantNarrowingCouldBeCircular.ts, 29, 15)) + + for (const key of ["a", "b", "c"]) { +>key : Symbol(key, Decl(discriminantNarrowingCouldBeCircular.ts, 31, 16)) + + const deeper = myObj2[key]; +>deeper : Symbol(deeper, Decl(discriminantNarrowingCouldBeCircular.ts, 32, 13)) +>myObj2 : Symbol(myObj2, Decl(discriminantNarrowingCouldBeCircular.ts, 29, 15)) +>key : Symbol(key, Decl(discriminantNarrowingCouldBeCircular.ts, 31, 16)) + + const deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; +>deeperKeys : Symbol(deeperKeys, Decl(discriminantNarrowingCouldBeCircular.ts, 33, 13)) +>isPlainObject2 : Symbol(isPlainObject2, Decl(discriminantNarrowingCouldBeCircular.ts, 23, 1)) +>deeper : Symbol(deeper, Decl(discriminantNarrowingCouldBeCircular.ts, 32, 13)) +>Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>deeper : Symbol(deeper, Decl(discriminantNarrowingCouldBeCircular.ts, 32, 13)) + } + } + diff --git a/tests/baselines/reference/discriminantNarrowingCouldBeCircular.types b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.types new file mode 100644 index 0000000000000..be59c4ebefa3f --- /dev/null +++ b/tests/baselines/reference/discriminantNarrowingCouldBeCircular.types @@ -0,0 +1,134 @@ +//// [tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts] //// + +=== discriminantNarrowingCouldBeCircular.ts === +// #57705, 57690 +declare function is(v: T): v is T; +>is : (v: T) => v is T +>v : T + +const o: Record | undefined = {}; +>o : Record | undefined +>{} : {} + +if (o) { +>o : Record + + for (const key in o) { +>key : string +>o : Record + + const value = o[key]; +>value : string +>o[key] : string +>o : Record +>key : string + + if (is(value)) { +>is(value) : boolean +>is : (v: T) => v is T +>value : string + } + } +} + +declare const kPresentationInheritanceParents: { [tagName: string]: string[] }; +>kPresentationInheritanceParents : { [tagName: string]: string[]; } +>tagName : string + +declare function parentElementOrShadowHost(element: Element): Element | undefined; +>parentElementOrShadowHost : (element: Element) => Element | undefined +>element : Element + +function getImplicitAriaRole(element: Element) { +>getImplicitAriaRole : (element: Element) => void +>element : Element + + let ancestor: Element | null = element; +>ancestor : any +>element : Element + + while (ancestor) { +>ancestor : any + + const parent = parentElementOrShadowHost(ancestor); +>parent : any +>parentElementOrShadowHost(ancestor) : any +>parentElementOrShadowHost : (element: Element) => any +>ancestor : any + + const parents = kPresentationInheritanceParents[ancestor.tagName]; +>parents : string[] +>kPresentationInheritanceParents[ancestor.tagName] : string[] +>kPresentationInheritanceParents : { [tagName: string]: string[]; } +>ancestor.tagName : any +>ancestor : any +>tagName : any + + if (!parents || !parent || !parents.includes(parent.tagName)) +>!parents || !parent || !parents.includes(parent.tagName) : boolean +>!parents || !parent : boolean +>!parents : false +>parents : string[] +>!parent : boolean +>parent : any +>!parents.includes(parent.tagName) : boolean +>parents.includes(parent.tagName) : boolean +>parents.includes : (searchElement: string, fromIndex?: number | undefined) => boolean +>parents : string[] +>includes : (searchElement: string, fromIndex?: number | undefined) => boolean +>parent.tagName : any +>parent : any +>tagName : any + + break; + ancestor = parent; +>ancestor = parent : any +>ancestor : any +>parent : any + } +} + +declare function isPlainObject2( +>isPlainObject2 : (data: unknown) => data is Record + + data: unknown, +>data : unknown + + ): data is Record; + + declare const myObj2: unknown; +>myObj2 : unknown + + if (isPlainObject2(myObj2)) { +>isPlainObject2(myObj2) : boolean +>isPlainObject2 : (data: unknown) => data is Record +>myObj2 : unknown + + for (const key of ["a", "b", "c"]) { +>key : string +>["a", "b", "c"] : string[] +>"a" : "a" +>"b" : "b" +>"c" : "c" + + const deeper = myObj2[key]; +>deeper : unknown +>myObj2[key] : unknown +>myObj2 : Record +>key : string + + const deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; +>deeperKeys : string[] +>isPlainObject2(deeper) ? Object.keys(deeper) : [] : string[] +>isPlainObject2(deeper) : boolean +>isPlainObject2 : (data: unknown) => data is Record +>deeper : unknown +>Object.keys(deeper) : string[] +>Object.keys : { (o: object): string[]; (o: {}): string[]; } +>Object : ObjectConstructor +>keys : { (o: object): string[]; (o: {}): string[]; } +>deeper : Record +>[] : never[] + } + } + diff --git a/tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=node16).js b/tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=node16).js index 8fefc3d2d6b56..a65aeaf84177b 100644 --- a/tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=node16).js +++ b/tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=node16).js @@ -31,7 +31,7 @@ declare module "tslib" { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.baz = exports.foo = exports.default = void 0; -var tslib_1 = require("tslib"); +const tslib_1 = require("tslib"); // cjs format file var fs_1 = require("fs"); Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(fs_1).default; } }); diff --git a/tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=nodenext).js b/tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=nodenext).js index 8fefc3d2d6b56..a65aeaf84177b 100644 --- a/tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=nodenext).js +++ b/tests/baselines/reference/nodeModulesAllowJsImportHelpersCollisions3(module=nodenext).js @@ -31,7 +31,7 @@ declare module "tslib" { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.baz = exports.foo = exports.default = void 0; -var tslib_1 = require("tslib"); +const tslib_1 = require("tslib"); // cjs format file var fs_1 = require("fs"); Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(fs_1).default; } }); diff --git a/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.symbols b/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.symbols index e1bacc007b26a..6c33043410585 100644 --- a/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.symbols +++ b/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.symbols @@ -28,9 +28,9 @@ if (isOneOf(fruit.kind, ['apple', 'banana'] as const)) { >const : Symbol(const) fruit.kind ->fruit.kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 22), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 41)) +>fruit.kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 22), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 41), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 62)) >fruit : Symbol(fruit, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 13)) ->kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 22), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 41)) +>kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 22), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 41), Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 62)) fruit >fruit : Symbol(fruit, Decl(typePredicatesCanNarrowByDiscriminant.ts, 1, 13)) @@ -54,9 +54,9 @@ if (isOneOf(kind, ['apple', 'banana'] as const)) { >const : Symbol(const) fruit2.kind ->fruit2.kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 23), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 42)) +>fruit2.kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 23), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 42), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 63)) >fruit2 : Symbol(fruit2, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 13)) ->kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 23), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 42)) +>kind : Symbol(kind, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 23), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 42), Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 63)) fruit2 >fruit2 : Symbol(fruit2, Decl(typePredicatesCanNarrowByDiscriminant.ts, 9, 13)) diff --git a/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.types b/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.types index 3dc7156b1fa08..bc14536bc8c5f 100644 --- a/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.types +++ b/tests/baselines/reference/typePredicatesCanNarrowByDiscriminant.types @@ -26,11 +26,11 @@ if (isOneOf(fruit.kind, ['apple', 'banana'] as const)) { fruit.kind >fruit.kind : "apple" | "banana" ->fruit : { kind: "apple"; } | { kind: "banana"; } +>fruit : { kind: "apple"; } | { kind: "banana"; } | { kind: "cherry"; } >kind : "apple" | "banana" fruit ->fruit : { kind: "apple"; } | { kind: "banana"; } +>fruit : { kind: "apple"; } | { kind: "banana"; } | { kind: "cherry"; } } declare const fruit2: { kind: 'apple'} | { kind: 'banana' } | { kind: 'cherry' } @@ -55,10 +55,10 @@ if (isOneOf(kind, ['apple', 'banana'] as const)) { >'banana' : "banana" fruit2.kind ->fruit2.kind : "apple" | "banana" ->fruit2 : { kind: "apple"; } | { kind: "banana"; } ->kind : "apple" | "banana" +>fruit2.kind : "apple" | "banana" | "cherry" +>fruit2 : { kind: "apple"; } | { kind: "banana"; } | { kind: "cherry"; } +>kind : "apple" | "banana" | "cherry" fruit2 ->fruit2 : { kind: "apple"; } | { kind: "banana"; } +>fruit2 : { kind: "apple"; } | { kind: "banana"; } | { kind: "cherry"; } } diff --git a/tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts b/tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts new file mode 100644 index 0000000000000..f05a8c8551e40 --- /dev/null +++ b/tests/cases/compiler/discriminantNarrowingCouldBeCircular.ts @@ -0,0 +1,39 @@ +// @strict: true +// @lib: es2022 + +// #57705, 57690 +declare function is(v: T): v is T; +const o: Record | undefined = {}; +if (o) { + for (const key in o) { + const value = o[key]; + if (is(value)) { + } + } +} + +declare const kPresentationInheritanceParents: { [tagName: string]: string[] }; +declare function parentElementOrShadowHost(element: Element): Element | undefined; + +function getImplicitAriaRole(element: Element) { + let ancestor: Element | null = element; + while (ancestor) { + const parent = parentElementOrShadowHost(ancestor); + const parents = kPresentationInheritanceParents[ancestor.tagName]; + if (!parents || !parent || !parents.includes(parent.tagName)) + break; + ancestor = parent; + } +} + +declare function isPlainObject2( + data: unknown, + ): data is Record; + + declare const myObj2: unknown; + if (isPlainObject2(myObj2)) { + for (const key of ["a", "b", "c"]) { + const deeper = myObj2[key]; + const deeperKeys = isPlainObject2(deeper) ? Object.keys(deeper) : []; + } + }