1/* 2* Copyright (c) Microsoft Corporation. All rights reserved. 3* Copyright (c) 2023 Huawei Device Co., Ltd. 4* Licensed under the Apache License, Version 2.0 (the "License"); 5* you may not use this file except in compliance with the License. 6* You may obtain a copy of the License at 7* 8* http://www.apache.org/licenses/LICENSE-2.0 9* 10* Unless required by applicable law or agreed to in writing, software 11* distributed under the License is distributed on an "AS IS" BASIS, 12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13* See the License for the specific language governing permissions and 14* limitations under the License. 15* 16* This file has been modified by Huawei to verify type inference by adding verification statements. 17*/ 18 19// === tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithIdenticalBCT.ts === 20declare function AssertType(value:any, type:string):void; 21//Cond ? Expr1 : Expr2, Expr1 and Expr2 have identical best common type 22class X { propertyX: any; propertyX1: number; propertyX2: string }; 23class A extends X { propertyA: number }; 24class B extends X { propertyB: string }; 25 26let x: X; 27AssertType(x, "X"); 28 29let a: A; 30AssertType(a, "A"); 31 32let b: B; 33AssertType(b, "B"); 34 35//Cond ? Expr1 : Expr2, Expr1 is supertype 36//Be Not contextually typed 37true ? x : a; 38AssertType(true ? x : a, "X"); 39AssertType(true, "boolean"); 40AssertType(x, "X"); 41AssertType(a, "A"); 42 43let result1 = true ? x : a; 44AssertType(result1, "X"); 45AssertType(true ? x : a, "X"); 46AssertType(true, "boolean"); 47AssertType(x, "X"); 48AssertType(a, "A"); 49 50//Expr1 and Expr2 are literals 51true ? {} : 1; 52AssertType(true ? {} : 1, "union"); 53AssertType(true, "boolean"); 54AssertType({}, "{}"); 55AssertType(1, "int"); 56 57true ? { a: 1 } : { a: 2, b: 'string' }; 58AssertType(true ? { a: 1 } : { a: 2, b: 'string' }, "union"); 59AssertType(true, "boolean"); 60AssertType({ a: 1 }, "{ a: number; }"); 61AssertType(a, "number"); 62AssertType(1, "int"); 63AssertType({ a: 2, b: 'string' }, "{ a: number; b: string; }"); 64AssertType(a, "number"); 65AssertType(2, "int"); 66AssertType(b, "string"); 67AssertType('string', "string"); 68 69let result2 = true ? {} : 1; 70AssertType(result2, "{}"); 71AssertType(true ? {} : 1, "union"); 72AssertType(true, "boolean"); 73AssertType({}, "{}"); 74AssertType(1, "int"); 75 76let result3 = true ? { a: 1 } : { a: 2, b: 'string' }; 77AssertType(result3, "union"); 78AssertType(true ? { a: 1 } : { a: 2, b: 'string' }, "union"); 79AssertType(true, "boolean"); 80AssertType({ a: 1 }, "{ a: number; }"); 81AssertType(a, "number"); 82AssertType(1, "int"); 83AssertType({ a: 2, b: 'string' }, "{ a: number; b: string; }"); 84AssertType(a, "number"); 85AssertType(2, "int"); 86AssertType(b, "string"); 87AssertType('string', "string"); 88 89//Contextually typed 90let resultIsX1: X = true ? x : a; 91AssertType(resultIsX1, "X"); 92AssertType(true ? x : a, "X"); 93AssertType(true, "boolean"); 94AssertType(x, "X"); 95AssertType(a, "A"); 96 97let result4: (t: A) => any = true ? (m) => m.propertyX : (n) => n.propertyA; 98AssertType(result4, "(A) => any"); 99AssertType(t, "A"); 100AssertType(true ? (m) => m.propertyX : (n) => n.propertyA, "(A) => any"); 101AssertType(true, "boolean"); 102AssertType((m) => m.propertyX, "(A) => any"); 103AssertType(m, "A"); 104AssertType(m.propertyX, "any"); 105AssertType((n) => n.propertyA, "(A) => number"); 106AssertType(n, "A"); 107AssertType(n.propertyA, "number"); 108 109//Cond ? Expr1 : Expr2, Expr2 is supertype 110//Be Not contextually typed 111true ? a : x; 112AssertType(true ? a : x, "X"); 113AssertType(true, "boolean"); 114AssertType(a, "A"); 115AssertType(x, "X"); 116 117let result5 = true ? a : x; 118AssertType(result5, "X"); 119AssertType(true ? a : x, "X"); 120AssertType(true, "boolean"); 121AssertType(a, "A"); 122AssertType(x, "X"); 123 124//Expr1 and Expr2 are literals 125true ? 1 : {}; 126AssertType(true ? 1 : {}, "union"); 127AssertType(true, "boolean"); 128AssertType(1, "int"); 129AssertType({}, "{}"); 130 131true ? { a: 2, b: 'string' } : { a: 1 }; 132AssertType(true ? { a: 2, b: 'string' } : { a: 1 }, "union"); 133AssertType(true, "boolean"); 134AssertType({ a: 2, b: 'string' }, "{ a: number; b: string; }"); 135AssertType(a, "number"); 136AssertType(2, "int"); 137AssertType(b, "string"); 138AssertType('string', "string"); 139AssertType({ a: 1 }, "{ a: number; }"); 140AssertType(a, "number"); 141AssertType(1, "int"); 142 143let result6 = true ? 1 : {}; 144AssertType(result6, "{}"); 145AssertType(true ? 1 : {}, "union"); 146AssertType(true, "boolean"); 147AssertType(1, "int"); 148AssertType({}, "{}"); 149 150let result7 = true ? { a: 2, b: 'string' } : { a: 1 }; 151AssertType(result7, "union"); 152AssertType(true ? { a: 2, b: 'string' } : { a: 1 }, "union"); 153AssertType(true, "boolean"); 154AssertType({ a: 2, b: 'string' }, "{ a: number; b: string; }"); 155AssertType(a, "number"); 156AssertType(2, "int"); 157AssertType(b, "string"); 158AssertType('string', "string"); 159AssertType({ a: 1 }, "{ a: number; }"); 160AssertType(a, "number"); 161AssertType(1, "int"); 162 163//Contextually typed 164let resultIsX2: X = true ? x : a; 165AssertType(resultIsX2, "X"); 166AssertType(true ? x : a, "X"); 167AssertType(true, "boolean"); 168AssertType(x, "X"); 169AssertType(a, "A"); 170 171let result8: (t: A) => any = true ? (m) => m.propertyA : (n) => n.propertyX; 172AssertType(result8, "(A) => any"); 173AssertType(t, "A"); 174AssertType(true ? (m) => m.propertyA : (n) => n.propertyX, "(A) => any"); 175AssertType(true, "boolean"); 176AssertType((m) => m.propertyA, "(A) => number"); 177AssertType(m, "A"); 178AssertType(m.propertyA, "number"); 179AssertType((n) => n.propertyX, "(A) => any"); 180AssertType(n, "A"); 181AssertType(n.propertyX, "any"); 182 183//Result = Cond ? Expr1 : Expr2, Result is supertype 184//Contextually typed 185let resultIsX3: X = true ? a : b; 186AssertType(resultIsX3, "X"); 187AssertType(true ? a : b, "union"); 188AssertType(true, "boolean"); 189AssertType(a, "A"); 190AssertType(b, "B"); 191 192let result10: (t: X) => any = true ? (m) => m.propertyX1 : (n) => n.propertyX2; 193AssertType(result10, "(X) => any"); 194AssertType(t, "X"); 195AssertType(true ? (m) => m.propertyX1 : (n) => n.propertyX2, "union"); 196AssertType(true, "boolean"); 197AssertType((m) => m.propertyX1, "(X) => number"); 198AssertType(m, "X"); 199AssertType(m.propertyX1, "number"); 200AssertType((n) => n.propertyX2, "(X) => string"); 201AssertType(n, "X"); 202AssertType(n.propertyX2, "string"); 203 204//Expr1 and Expr2 are literals 205let result11: any = true ? 1 : 'string'; 206AssertType(result11, "any"); 207AssertType(true ? 1 : 'string', "union"); 208AssertType(true, "boolean"); 209AssertType(1, "int"); 210AssertType('string', "string"); 211 212 213