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/compiler/intersectionTypeNormalization.ts === 20declare function AssertType(value:any, type:string):void; 21interface A { a: string } 22interface B { b: string } 23interface C { c: string } 24interface D { d: string } 25 26// Identical ways of writing the same type 27type X1 = (A | B) & (C | D); 28type X2 = A & (C | D) | B & (C | D) 29type X3 = A & C | A & D | B & C | B & D; 30 31let x: X1; 32AssertType(x, "X1"); 33 34let x: X2; 35AssertType(x, "X1"); 36 37let x: X3; 38AssertType(x, "X1"); 39 40interface X { x: string } 41interface Y { y: string } 42 43// Identical ways of writing the same type 44type Y1 = (A | X & Y) & (C | D); 45type Y2 = A & (C | D) | X & Y & (C | D) 46type Y3 = A & C | A & D | X & Y & C | X & Y & D; 47 48let y: Y1; 49AssertType(y, "Y1"); 50 51let y: Y2; 52AssertType(y, "Y1"); 53 54let y: Y3; 55AssertType(y, "Y1"); 56 57interface M { m: string } 58interface N { n: string } 59 60// Identical ways of writing the same type 61type Z1 = (A | X & (M | N)) & (C | D); 62type Z2 = A & (C | D) | X & (M | N) & (C | D) 63type Z3 = A & C | A & D | X & (M | N) & C | X & (M | N) & D; 64type Z4 = A & C | A & D | X & M & C | X & N & C | X & M & D | X & N & D; 65 66let z: Z1; 67AssertType(z, "Z1"); 68 69let z: Z2; 70AssertType(z, "Z1"); 71 72let z: Z3; 73AssertType(z, "Z1"); 74 75let z: Z4; 76AssertType(z, "Z1"); 77 78// Repro from #9919 79 80type ToString = { 81 toString(): string; 82} 83 84type BoxedValue = { kind: 'int', num: number } 85 | { kind: 'string', str: string } 86 87type IntersectionFail = BoxedValue & ToString 88 89type IntersectionInline = { kind: 'int', num: number } & ToString 90 | { kind: 'string', str: string } & ToString 91 92function getValueAsString(value: IntersectionFail): string { 93 if (value.kind === 'int') { 94AssertType(value.kind === 'int', "boolean"); 95AssertType(value.kind, "union"); 96AssertType('int', "string"); 97 98AssertType('' + value.num, "string"); 99AssertType('', "string"); 100AssertType(value.num, "number"); 101 return '' + value.num; 102 } 103AssertType(value.str, "string"); 104 return value.str; 105} 106 107// Repro from #12535 108 109namespace enums { 110 export const enum A { 111 a1, 112 a2, 113 a3, 114 // ... elements omitted for the sake of clarity 115 a75, 116 a76, 117 a77, 118 } 119 export const enum B { 120 b1, 121 b2, 122 // ... elements omitted for the sake of clarity 123 b86, 124 b87, 125 } 126 export const enum C { 127 c1, 128 c2, 129 // ... elements omitted for the sake of clarity 130 c210, 131 c211, 132 } 133 export type Genre = A | B | C; 134} 135 136type Foo = { 137 genreId: enums.Genre; 138}; 139 140type Bar = { 141 genreId: enums.Genre; 142}; 143 144type FooBar = Foo & Bar; 145 146function foo(so: any) { 147 const val = so as FooBar; 148AssertType(val, "FooBar"); 149AssertType(so as FooBar, "FooBar"); 150AssertType(so, "any"); 151 152 const isGenre = val.genreId; 153AssertType(isGenre, "enums.Genre"); 154AssertType(val.genreId, "enums.Genre"); 155 156AssertType(isGenre, "enums.Genre"); 157 return isGenre; 158} 159 160