• 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/typeGuardOfFromPropNameInUnionType.ts ===
20declare function AssertType(value:any, type:string):void;
21class A { a: string; }
22class B { b: number; }
23class C { b: Object; }
24class D { a: Date; }
25
26function namedClasses(x: A | B) {
27    if ("a" in x) {
28AssertType("a" in x, "boolean");
29AssertType("a", "string");
30AssertType(x, "union");
31
32        x.a = "1";
33AssertType(x.a = "1", "string");
34AssertType(x.a, "string");
35AssertType("1", "string");
36
37    } else {
38        x.b = 1;
39AssertType(x.b = 1, "int");
40AssertType(x.b, "number");
41AssertType(1, "int");
42    }
43}
44
45function multipleClasses(x: A | B | C | D) {
46    if ("a" in x) {
47AssertType("a" in x, "boolean");
48AssertType("a", "string");
49AssertType(x, "union");
50
51        let y: string | Date = x.a;
52AssertType(y, "union");
53AssertType(x.a, "union");
54
55    } else {
56        let z: number | Object = x.b;
57AssertType(z, "union");
58AssertType(x.b, "union");
59    }
60}
61
62function anonymousClasses(x: { a: string; } | { b: number; }) {
63    if ("a" in x) {
64AssertType("a" in x, "boolean");
65AssertType("a", "string");
66AssertType(x, "union");
67
68        let y: string = x.a;
69AssertType(y, "string");
70AssertType(x.a, "string");
71
72    } else {
73        let z: number = x.b;
74AssertType(z, "number");
75AssertType(x.b, "number");
76    }
77}
78
79class AWithOptionalProp { a?: string; }
80class BWithOptionalProp { b?: string; }
81
82function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
83    if ("a" in x) {
84AssertType("a" in x, "boolean");
85AssertType("a", "string");
86AssertType(x, "union");
87
88        x.a = "1";
89AssertType(x.a = "1", "string");
90AssertType(x.a, "string");
91AssertType("1", "string");
92
93    } else {
94        const y: string = x instanceof AWithOptionalProp
95AssertType(y, "string");
96AssertType(x instanceof AWithOptionalProp            ? x.a            : x.b, "string");
97AssertType(x instanceof AWithOptionalProp, "boolean");
98AssertType(x, "union");
99AssertType(AWithOptionalProp, "typeof AWithOptionalProp");
100
101            ? x.a
102AssertType(x.a, "string");
103
104            : x.b
105AssertType(x.b, "string");
106    }
107}
108
109function inParenthesizedExpression(x: A | B) {
110    if ("a" in (x)) {
111AssertType("a" in (x), "boolean");
112AssertType("a", "string");
113AssertType((x), "union");
114AssertType(x, "union");
115
116        let y: string = x.a;
117AssertType(y, "string");
118AssertType(x.a, "string");
119
120    } else {
121        let z: number = x.b;
122AssertType(z, "number");
123AssertType(x.b, "number");
124    }
125}
126
127class ClassWithUnionProp { prop: A | B; }
128
129function inProperty(x: ClassWithUnionProp) {
130    if ("a" in x.prop) {
131AssertType("a" in x.prop, "boolean");
132AssertType("a", "string");
133AssertType(x.prop, "union");
134
135        let y: string = x.prop.a;
136AssertType(y, "string");
137AssertType(x.prop.a, "string");
138AssertType(x.prop, "A");
139
140    } else {
141        let z: number = x.prop.b;
142AssertType(z, "number");
143AssertType(x.prop.b, "number");
144AssertType(x.prop, "B");
145    }
146}
147
148class NestedClassWithProp { outer: ClassWithUnionProp; }
149
150function innestedProperty(x: NestedClassWithProp) {
151    if ("a" in x.outer.prop) {
152AssertType("a" in x.outer.prop, "boolean");
153AssertType("a", "string");
154AssertType(x.outer.prop, "union");
155AssertType(x.outer, "ClassWithUnionProp");
156
157        let y: string = x.outer.prop.a;
158AssertType(y, "string");
159AssertType(x.outer.prop.a, "string");
160AssertType(x.outer.prop, "A");
161AssertType(x.outer, "ClassWithUnionProp");
162
163    } else {
164        let z: number = x.outer.prop.b;
165AssertType(z, "number");
166AssertType(x.outer.prop.b, "number");
167AssertType(x.outer.prop, "B");
168AssertType(x.outer, "ClassWithUnionProp");
169    }
170}
171
172class InMemberOfClass {
173    protected prop: A | B;
174    inThis() {
175        if ("a" in this.prop) {
176AssertType("a" in this.prop, "boolean");
177AssertType("a", "string");
178AssertType(this.prop, "union");
179AssertType(this, "this");
180
181            let y: string = this.prop.a;
182AssertType(y, "string");
183AssertType(this.prop.a, "string");
184AssertType(this.prop, "A");
185AssertType(this, "this");
186
187        } else {
188            let z: number = this.prop.b;
189AssertType(z, "number");
190AssertType(this.prop.b, "number");
191AssertType(this.prop, "B");
192AssertType(this, "this");
193        }
194    }
195}
196
197// added for completeness
198class SelfAssert {
199    a: string;
200    inThis() {
201        if ("a" in this) {
202AssertType("a" in this, "boolean");
203AssertType("a", "string");
204AssertType(this, "this");
205
206            let y: string = this.a;
207AssertType(y, "string");
208AssertType(this.a, "string");
209AssertType(this, "this");
210
211        } else {
212        }
213    }
214}
215
216interface Indexed {
217    [s: string]: any;
218}
219
220function f(i: Indexed) {
221    if ("a" in i) {
222AssertType("a" in i, "boolean");
223AssertType("a", "string");
224AssertType(i, "Indexed");
225
226AssertType(i.a, "any");
227        return i.a;
228    }
229    else if ("b" in i) {
230AssertType("b" in i, "boolean");
231AssertType("b", "string");
232AssertType(i, "Indexed");
233
234AssertType(i.b, "any");
235        return i.b;
236    }
237AssertType("c" in i && i.c, "any");
238AssertType("c" in i, "boolean");
239AssertType("c", "string");
240AssertType(i, "Indexed");
241AssertType(i.c, "any");
242    return "c" in i && i.c;
243}
244
245
246