• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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