• 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/controlFlow/typeGuardsNestedAssignments.ts ===
20declare function AssertType(value:any, type:string):void;
21class Foo {
22    x: string;
23}
24
25declare function getFooOrNull(): Foo | null;
26declare function getStringOrNumberOrNull(): string | number | null;
27
28function f1() {
29    let foo: Foo | null;
30AssertType(foo, "union");
31AssertType(null, "null");
32
33    if ((foo = getFooOrNull()) !== null) {
34AssertType((foo = getFooOrNull()) !== null, "boolean");
35AssertType((foo = getFooOrNull()), "union");
36AssertType(foo = getFooOrNull(), "union");
37AssertType(foo, "union");
38AssertType(getFooOrNull(), "union");
39AssertType(getFooOrNull, "() => union");
40AssertType(null, "null");
41
42        foo;  // Foo
43AssertType(foo, "Foo");
44    }
45}
46
47function f2() {
48    let foo1: Foo | null;
49AssertType(foo1, "union");
50AssertType(null, "null");
51
52    let foo2: Foo | null;
53AssertType(foo2, "union");
54AssertType(null, "null");
55
56    if ((foo1 = getFooOrNull(), foo2 = foo1) !== null) {
57AssertType((foo1 = getFooOrNull(), foo2 = foo1) !== null, "boolean");
58AssertType((foo1 = getFooOrNull(), foo2 = foo1), "union");
59AssertType(foo1 = getFooOrNull(), foo2 = foo1, "union");
60AssertType(foo1 = getFooOrNull(), "union");
61AssertType(foo1, "union");
62AssertType(getFooOrNull(), "union");
63AssertType(getFooOrNull, "() => union");
64AssertType(foo2 = foo1, "union");
65AssertType(foo2, "union");
66AssertType(foo1, "union");
67AssertType(null, "null");
68
69        foo1;  // Foo | null
70AssertType(foo1, "union");
71
72        foo2;  // Foo
73AssertType(foo2, "Foo");
74    }
75}
76
77function f3() {
78    let obj: Object | null;
79AssertType(obj, "union");
80AssertType(null, "null");
81
82    if ((obj = getFooOrNull()) instanceof Foo) {
83AssertType((obj = getFooOrNull()) instanceof Foo, "boolean");
84AssertType((obj = getFooOrNull()), "union");
85AssertType(obj = getFooOrNull(), "union");
86AssertType(obj, "union");
87AssertType(getFooOrNull(), "union");
88AssertType(getFooOrNull, "() => union");
89AssertType(Foo, "typeof Foo");
90
91        obj;
92AssertType(obj, "Foo");
93    }
94}
95
96function f4() {
97    let x: string | number | null;
98AssertType(x, "union");
99AssertType(null, "null");
100
101    if (typeof (x = getStringOrNumberOrNull()) === "number") {
102AssertType(typeof (x = getStringOrNumberOrNull()) === "number", "boolean");
103AssertType(typeof (x = getStringOrNumberOrNull()), "union");
104AssertType((x = getStringOrNumberOrNull()), "union");
105AssertType(x = getStringOrNumberOrNull(), "union");
106AssertType(x, "union");
107AssertType(getStringOrNumberOrNull(), "union");
108AssertType(getStringOrNumberOrNull, "() => union");
109AssertType("number", "string");
110
111        x;
112AssertType(x, "number");
113    }
114}
115
116// Repro from #8851
117
118const re = /./g
119AssertType(re, "RegExp");
120AssertType(/./g, "RegExp");
121
122let match: RegExpExecArray | null
123AssertType(match, "union");
124AssertType(null, "null");
125
126while ((match = re.exec("xxx")) != null) {
127    const length = match[1].length + match[2].length
128AssertType(length, "number");
129AssertType(match[1].length + match[2].length, "number");
130AssertType(match[1].length, "number");
131AssertType(match[1], "string");
132AssertType(match, "RegExpExecArray");
133AssertType(1, "int");
134AssertType(match[2].length, "number");
135AssertType(match[2], "string");
136AssertType(match, "RegExpExecArray");
137AssertType(2, "int");
138}
139
140