diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.symbols b/tests/baselines/reference/controlFlowBinaryOrExpression.symbols index 217e11dc95d..5251973005f 100644 --- a/tests/baselines/reference/controlFlowBinaryOrExpression.symbols +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.symbols @@ -64,25 +64,13 @@ if (isNodeList(sourceObj)) { >sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) sourceObj.length; ->sourceObj.length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +>sourceObj.length : Symbol(length, Decl(controlFlowBinaryOrExpression.ts, 10, 27), Decl(controlFlowBinaryOrExpression.ts, 14, 33)) >sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) ->length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +>length : Symbol(length, Decl(controlFlowBinaryOrExpression.ts, 10, 27), Decl(controlFlowBinaryOrExpression.ts, 14, 33)) } if (isHTMLCollection(sourceObj)) { >isHTMLCollection : Symbol(isHTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 18, 67)) ->sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) - - sourceObj.length; ->sourceObj.length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) ->sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) ->length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) -} - -if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { ->isNodeList : Symbol(isNodeList, Decl(controlFlowBinaryOrExpression.ts, 16, 1)) ->sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) ->isHTMLCollection : Symbol(isHTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 18, 67)) >sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) sourceObj.length; @@ -91,3 +79,15 @@ if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { >length : Symbol(length, Decl(controlFlowBinaryOrExpression.ts, 10, 27), Decl(controlFlowBinaryOrExpression.ts, 14, 33)) } +if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { +>isNodeList : Symbol(isNodeList, Decl(controlFlowBinaryOrExpression.ts, 16, 1)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) +>isHTMLCollection : Symbol(isHTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 18, 67)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) + + sourceObj.length; +>sourceObj.length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) +>length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +} + diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.types b/tests/baselines/reference/controlFlowBinaryOrExpression.types index 3634a322396..e843844ebf1 100644 --- a/tests/baselines/reference/controlFlowBinaryOrExpression.types +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.types @@ -80,7 +80,7 @@ if (isNodeList(sourceObj)) { sourceObj.length; >sourceObj.length : number ->sourceObj : NodeList +>sourceObj : NodeList | HTMLCollection >length : number } @@ -91,7 +91,7 @@ if (isHTMLCollection(sourceObj)) { sourceObj.length; >sourceObj.length : number ->sourceObj : HTMLCollection +>sourceObj : NodeList | HTMLCollection >length : number } @@ -102,11 +102,11 @@ if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { >sourceObj : NodeList | HTMLCollection | { a: string; } >isHTMLCollection(sourceObj) : boolean >isHTMLCollection : (sourceObj: any) => sourceObj is HTMLCollection ->sourceObj : HTMLCollection | { a: string; } +>sourceObj : { a: string; } sourceObj.length; >sourceObj.length : number ->sourceObj : NodeList | HTMLCollection +>sourceObj : NodeList >length : number } diff --git a/tests/baselines/reference/instanceofWithStructurallyIdenticalTypes.errors.txt b/tests/baselines/reference/instanceofWithStructurallyIdenticalTypes.errors.txt new file mode 100644 index 00000000000..3f1e210d7b4 --- /dev/null +++ b/tests/baselines/reference/instanceofWithStructurallyIdenticalTypes.errors.txt @@ -0,0 +1,76 @@ +tests/cases/compiler/instanceofWithStructurallyIdenticalTypes.ts(32,18): error TS2339: Property 'item' does not exist on type 'never'. + + +==== tests/cases/compiler/instanceofWithStructurallyIdenticalTypes.ts (1 errors) ==== + // Repro from #7271 + + class C1 { item: string } + class C2 { item: string[] } + class C3 { item: string } + + function foo1(x: C1 | C2 | C3): string { + if (x instanceof C1) { + return x.item; + } + else if (x instanceof C2) { + return x.item[0]; + } + else if (x instanceof C3) { + return x.item; + } + return "error"; + } + + function isC1(c: C1 | C2 | C3): c is C1 { return c instanceof C1 } + function isC2(c: C1 | C2 | C3): c is C2 { return c instanceof C2 } + function isC3(c: C1 | C2 | C3): c is C3 { return c instanceof C3 } + + function foo2(x: C1 | C2 | C3): string { + if (isC1(x)) { + return x.item; + } + else if (isC2(x)) { + return x.item[0]; + } + else if (isC3(x)) { + return x.item; + ~~~~ +!!! error TS2339: Property 'item' does not exist on type 'never'. + } + return "error"; + } + + // More tests + + class A { a: string } + class A1 extends A { } + class A2 { a: string } + class B extends A { b: string } + + function goo(x: A) { + if (x instanceof A) { + x; // A + } + else { + x; // never + } + if (x instanceof A1) { + x; // A1 + } + else { + x; // A + } + if (x instanceof A2) { + x; // A2 + } + else { + x; // A + } + if (x instanceof B) { + x; // B + } + else { + x; // A + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/typePredicateStructuralMatch.errors.txt b/tests/baselines/reference/typePredicateStructuralMatch.errors.txt deleted file mode 100644 index 72cf04ddeb0..00000000000 --- a/tests/baselines/reference/typePredicateStructuralMatch.errors.txt +++ /dev/null @@ -1,36 +0,0 @@ -tests/cases/compiler/typePredicateStructuralMatch.ts(17,12): error TS2322: Type 'Result[] | { data: Result[]; }' is not assignable to type 'Result[]'. - Type '{ data: Result[]; }' is not assignable to type 'Result[]'. - Property 'length' is missing in type '{ data: Result[]; }'. - - -==== tests/cases/compiler/typePredicateStructuralMatch.ts (1 errors) ==== - // Repro from #12235 - - getResults1([]); - getResults1({data: []}); - - getResults2([]); - getResults2({data: []}); - - type Result = { value: string }; - type Results = Result[]; - - function isResponseInData(value: T | { data: T}): value is { data: T } { - return value.hasOwnProperty('data'); - } - - function getResults1(value: Results | { data: Results }): Results { - return isResponseInData(value) ? value.data : value; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type 'Result[] | { data: Result[]; }' is not assignable to type 'Result[]'. -!!! error TS2322: Type '{ data: Result[]; }' is not assignable to type 'Result[]'. -!!! error TS2322: Property 'length' is missing in type '{ data: Result[]; }'. - } - - function isPlainResponse(value: T | { data: T}): value is T { - return !value.hasOwnProperty('data'); - } - - function getResults2(value: Results | { data: Results }): Results { - return isPlainResponse(value) ? value : value.data; - } \ No newline at end of file diff --git a/tests/baselines/reference/typePredicateStructuralMatch.symbols b/tests/baselines/reference/typePredicateStructuralMatch.symbols new file mode 100644 index 00000000000..59d548d4bfc --- /dev/null +++ b/tests/baselines/reference/typePredicateStructuralMatch.symbols @@ -0,0 +1,91 @@ +=== tests/cases/compiler/typePredicateStructuralMatch.ts === +// Repro from #12235 + +getResults1([]); +>getResults1 : Symbol(getResults1, Decl(typePredicateStructuralMatch.ts, 13, 1)) + +getResults1({data: []}); +>getResults1 : Symbol(getResults1, Decl(typePredicateStructuralMatch.ts, 13, 1)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 3, 13)) + +getResults2([]); +>getResults2 : Symbol(getResults2, Decl(typePredicateStructuralMatch.ts, 21, 1)) + +getResults2({data: []}); +>getResults2 : Symbol(getResults2, Decl(typePredicateStructuralMatch.ts, 21, 1)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 6, 13)) + +type Result = { value: string }; +>Result : Symbol(Result, Decl(typePredicateStructuralMatch.ts, 6, 24)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 8, 15)) + +type Results = Result[]; +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) +>Result : Symbol(Result, Decl(typePredicateStructuralMatch.ts, 6, 24)) + +function isResponseInData(value: T | { data: T}): value is { data: T } { +>isResponseInData : Symbol(isResponseInData, Decl(typePredicateStructuralMatch.ts, 9, 24)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 11, 26)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 11, 29)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 11, 26)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 11, 41)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 11, 26)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 11, 29)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 11, 63)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 11, 26)) + + return value.hasOwnProperty('data'); +>value.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.d.ts, --, --)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 11, 29)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.d.ts, --, --)) +} + +function getResults1(value: Results | { data: Results }): Results { +>getResults1 : Symbol(getResults1, Decl(typePredicateStructuralMatch.ts, 13, 1)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 15, 21)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 15, 39)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) + + return isResponseInData(value) ? value.data : value; +>isResponseInData : Symbol(isResponseInData, Decl(typePredicateStructuralMatch.ts, 9, 24)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 15, 21)) +>value.data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 15, 39)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 15, 21)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 15, 39)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 15, 21)) +} + +function isPlainResponse(value: T | { data: T}): value is T { +>isPlainResponse : Symbol(isPlainResponse, Decl(typePredicateStructuralMatch.ts, 17, 1)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 19, 25)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 19, 28)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 19, 25)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 19, 40)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 19, 25)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 19, 28)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 19, 25)) + + return !value.hasOwnProperty('data'); +>value.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.d.ts, --, --)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 19, 28)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.d.ts, --, --)) +} + +function getResults2(value: Results | { data: Results }): Results { +>getResults2 : Symbol(getResults2, Decl(typePredicateStructuralMatch.ts, 21, 1)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 23, 21)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 23, 39)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) + + return isPlainResponse(value) ? value : value.data; +>isPlainResponse : Symbol(isPlainResponse, Decl(typePredicateStructuralMatch.ts, 17, 1)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 23, 21)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 23, 21)) +>value.data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 23, 39)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 23, 21)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 23, 39)) +} diff --git a/tests/baselines/reference/typePredicateStructuralMatch.types b/tests/baselines/reference/typePredicateStructuralMatch.types new file mode 100644 index 00000000000..9f7a129da15 --- /dev/null +++ b/tests/baselines/reference/typePredicateStructuralMatch.types @@ -0,0 +1,110 @@ +=== tests/cases/compiler/typePredicateStructuralMatch.ts === +// Repro from #12235 + +getResults1([]); +>getResults1([]) : Result[] +>getResults1 : (value: Result[] | { data: Result[]; }) => Result[] +>[] : undefined[] + +getResults1({data: []}); +>getResults1({data: []}) : Result[] +>getResults1 : (value: Result[] | { data: Result[]; }) => Result[] +>{data: []} : { data: undefined[]; } +>data : undefined[] +>[] : undefined[] + +getResults2([]); +>getResults2([]) : Result[] +>getResults2 : (value: Result[] | { data: Result[]; }) => Result[] +>[] : undefined[] + +getResults2({data: []}); +>getResults2({data: []}) : Result[] +>getResults2 : (value: Result[] | { data: Result[]; }) => Result[] +>{data: []} : { data: undefined[]; } +>data : undefined[] +>[] : undefined[] + +type Result = { value: string }; +>Result : Result +>value : string + +type Results = Result[]; +>Results : Result[] +>Result : Result + +function isResponseInData(value: T | { data: T}): value is { data: T } { +>isResponseInData : (value: T | { data: T; }) => value is { data: T; } +>T : T +>value : T | { data: T; } +>T : T +>data : T +>T : T +>value : any +>data : T +>T : T + + return value.hasOwnProperty('data'); +>value.hasOwnProperty('data') : boolean +>value.hasOwnProperty : (v: string) => boolean +>value : T | { data: T; } +>hasOwnProperty : (v: string) => boolean +>'data' : "data" +} + +function getResults1(value: Results | { data: Results }): Results { +>getResults1 : (value: Result[] | { data: Result[]; }) => Result[] +>value : Result[] | { data: Result[]; } +>Results : Result[] +>data : Result[] +>Results : Result[] +>Results : Result[] + + return isResponseInData(value) ? value.data : value; +>isResponseInData(value) ? value.data : value : Result[] +>isResponseInData(value) : boolean +>isResponseInData : (value: T | { data: T; }) => value is { data: T; } +>value : Result[] | { data: Result[]; } +>value.data : Result[] +>value : { data: Result[]; } +>data : Result[] +>value : Result[] +} + +function isPlainResponse(value: T | { data: T}): value is T { +>isPlainResponse : (value: T | { data: T; }) => value is T +>T : T +>value : T | { data: T; } +>T : T +>data : T +>T : T +>value : any +>T : T + + return !value.hasOwnProperty('data'); +>!value.hasOwnProperty('data') : boolean +>value.hasOwnProperty('data') : boolean +>value.hasOwnProperty : (v: string) => boolean +>value : T | { data: T; } +>hasOwnProperty : (v: string) => boolean +>'data' : "data" +} + +function getResults2(value: Results | { data: Results }): Results { +>getResults2 : (value: Result[] | { data: Result[]; }) => Result[] +>value : Result[] | { data: Result[]; } +>Results : Result[] +>data : Result[] +>Results : Result[] +>Results : Result[] + + return isPlainResponse(value) ? value : value.data; +>isPlainResponse(value) ? value : value.data : Result[] +>isPlainResponse(value) : boolean +>isPlainResponse : (value: T | { data: T; }) => value is T +>value : Result[] | { data: Result[]; } +>value : Result[] +>value.data : Result[] +>value : { data: Result[]; } +>data : Result[] +}