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/typeGuards/typeGuardOfFormExpr1AndExpr2.ts === 20declare function AssertType(value:any, type:string):void; 21let str: string; 22AssertType(str, "string"); 23 24let bool: boolean; 25AssertType(bool, "boolean"); 26 27let num: number; 28AssertType(num, "number"); 29 30let strOrNum: string | number; 31AssertType(strOrNum, "union"); 32 33let strOrNumOrBool: string | number | boolean; 34AssertType(strOrNumOrBool, "union"); 35 36let numOrBool: number | boolean; 37AssertType(numOrBool, "union"); 38 39class C { private p; } 40let c: C; 41AssertType(c, "C"); 42 43let cOrBool: C| boolean; 44AssertType(cOrBool, "union"); 45 46let strOrNumOrBoolOrC: string | number | boolean | C; 47AssertType(strOrNumOrBoolOrC, "union"); 48 49// A type guard of the form expr1 && expr2 50// - when true, narrows the type of x by expr1 when true and then by expr2 when true, or 51// - when false, narrows the type of x to T1 | T2, where T1 is the type of x narrowed by expr1 when 52// false, and T2 is the type of x narrowed by expr1 when true and then by expr2 when false. 53 54// (typeguard1 && typeguard2) 55if (typeof strOrNumOrBool !== "string" && typeof strOrNumOrBool !== "number") { 56 bool = strOrNumOrBool; // boolean 57AssertType(bool = strOrNumOrBool, "boolean"); 58AssertType(bool, "boolean"); 59AssertType(strOrNumOrBool, "boolean"); 60} 61else { 62 strOrNum = strOrNumOrBool; // string | number 63AssertType(strOrNum = strOrNumOrBool, "union"); 64AssertType(strOrNum, "union"); 65AssertType(strOrNumOrBool, "union"); 66} 67// (typeguard1 && typeguard2 && typeguard3) 68if (typeof strOrNumOrBoolOrC !== "string" && typeof strOrNumOrBoolOrC !== "number" && typeof strOrNumOrBoolOrC !== "boolean") { 69 c = strOrNumOrBoolOrC; // C 70AssertType(c = strOrNumOrBoolOrC, "C"); 71AssertType(c, "C"); 72AssertType(strOrNumOrBoolOrC, "C"); 73} 74else { 75 strOrNumOrBool = strOrNumOrBoolOrC; // string | number | boolean 76AssertType(strOrNumOrBool = strOrNumOrBoolOrC, "union"); 77AssertType(strOrNumOrBool, "union"); 78AssertType(strOrNumOrBoolOrC, "union"); 79} 80// (typeguard1 && typeguard2 && typeguard11(onAnotherType)) 81if (typeof strOrNumOrBoolOrC !== "string" && typeof strOrNumOrBoolOrC !== "number" && typeof strOrNumOrBool === "boolean") { 82 cOrBool = strOrNumOrBoolOrC; // C | boolean 83AssertType(cOrBool = strOrNumOrBoolOrC, "union"); 84AssertType(cOrBool, "union"); 85AssertType(strOrNumOrBoolOrC, "union"); 86 87 bool = strOrNumOrBool; // boolean 88AssertType(bool = strOrNumOrBool, "boolean"); 89AssertType(bool, "boolean"); 90AssertType(strOrNumOrBool, "boolean"); 91} 92else { 93 let r1: string | number | boolean | C = strOrNumOrBoolOrC; // string | number | boolean | C 94AssertType(r1, "union"); 95AssertType(strOrNumOrBoolOrC, "union"); 96 97 let r2: string | number | boolean = strOrNumOrBool; 98AssertType(r2, "union"); 99AssertType(strOrNumOrBool, "union"); 100} 101// (typeguard1) && simpleExpr 102if (typeof strOrNumOrBool !== "string" && numOrBool !== strOrNumOrBool) { 103 numOrBool = strOrNumOrBool; // number | boolean 104AssertType(numOrBool = strOrNumOrBool, "union"); 105AssertType(numOrBool, "union"); 106AssertType(strOrNumOrBool, "union"); 107} 108else { 109 let r3: string | number | boolean = strOrNumOrBool; // string | number | boolean 110AssertType(r3, "union"); 111AssertType(strOrNumOrBool, "union"); 112} 113 114