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/types/typeAliases/genericTypeAliases.ts === 20declare function AssertType(value:any, type:string):void; 21type Tree<T> = T | { left: Tree<T>, right: Tree<T> }; 22 23let tree: Tree<number> = { 24AssertType(tree, "Tree<number>"); 25AssertType({ left: { left: 0, right: { left: 1, right: 2 }, }, right: 3}, "{ left: { left: number; right: { left: number; right: number; }; }; right: number; }"); 26 27 left: { 28AssertType(left, "{ left: number; right: { left: number; right: number; }; }"); 29AssertType({ left: 0, right: { left: 1, right: 2 }, }, "{ left: number; right: { left: number; right: number; }; }"); 30 31 left: 0, 32AssertType(left, "number"); 33AssertType(0, "int"); 34 35 right: { 36AssertType(right, "{ left: number; right: number; }"); 37AssertType({ left: 1, right: 2 }, "{ left: number; right: number; }"); 38 39 left: 1, 40AssertType(left, "number"); 41AssertType(1, "int"); 42 43 right: 2 44AssertType(right, "number"); 45AssertType(2, "int"); 46 47 }, 48 }, 49 right: 3 50AssertType(right, "number"); 51AssertType(3, "int"); 52 53}; 54 55type Lazy<T> = T | (() => T); 56 57let ls: Lazy<string>; 58AssertType(ls, "Lazy<string>"); 59 60ls = "eager"; 61AssertType(ls = "eager", "string"); 62AssertType(ls, "Lazy<string>"); 63AssertType("eager", "string"); 64 65ls = () => "lazy"; 66AssertType(ls = () => "lazy", "() => string"); 67AssertType(ls, "Lazy<string>"); 68AssertType(() => "lazy", "() => string"); 69AssertType("lazy", "string"); 70 71type Foo<T> = T | { x: Foo<T> }; 72type Bar<U> = U | { x: Bar<U> }; 73 74// Deeply instantiated generics 75let x: Foo<string>; 76AssertType(x, "Foo<string>"); 77 78let y: Bar<string>; 79AssertType(y, "Bar<string>"); 80 81x = y; 82AssertType(x = y, "Bar<string>"); 83AssertType(x, "Foo<string>"); 84AssertType(y, "Bar<string>"); 85 86y = x; 87AssertType(y = x, "Foo<string>"); 88AssertType(y, "Bar<string>"); 89AssertType(x, "Foo<string>"); 90 91x = "string"; 92AssertType(x = "string", "string"); 93AssertType(x, "Foo<string>"); 94AssertType("string", "string"); 95 96x = { x: "hello" }; 97AssertType(x = { x: "hello" }, "{ x: string; }"); 98AssertType(x, "Foo<string>"); 99AssertType({ x: "hello" }, "{ x: string; }"); 100AssertType(x, "string"); 101AssertType("hello", "string"); 102 103x = { x: { x: "world" } }; 104AssertType(x = { x: { x: "world" } }, "{ x: { x: string; }; }"); 105AssertType(x, "Foo<string>"); 106AssertType({ x: { x: "world" } }, "{ x: { x: string; }; }"); 107AssertType(x, "{ x: string; }"); 108AssertType({ x: "world" }, "{ x: string; }"); 109AssertType(x, "string"); 110AssertType("world", "string"); 111 112let z: Foo<number>; 113AssertType(z, "Foo<number>"); 114 115z = 42; 116AssertType(z = 42, "int"); 117AssertType(z, "Foo<number>"); 118AssertType(42, "int"); 119 120z = { x: 42 }; 121AssertType(z = { x: 42 }, "{ x: number; }"); 122AssertType(z, "Foo<number>"); 123AssertType({ x: 42 }, "{ x: number; }"); 124AssertType(x, "number"); 125AssertType(42, "int"); 126 127z = { x: { x: 42 } }; 128AssertType(z = { x: { x: 42 } }, "{ x: { x: number; }; }"); 129AssertType(z, "Foo<number>"); 130AssertType({ x: { x: 42 } }, "{ x: { x: number; }; }"); 131AssertType(x, "{ x: number; }"); 132AssertType({ x: 42 }, "{ x: number; }"); 133AssertType(x, "number"); 134AssertType(42, "int"); 135 136type Strange<T> = string; // Type parameter not used 137let s: Strange<number>; 138AssertType(s, "string"); 139 140s = "hello"; 141AssertType(s = "hello", "string"); 142AssertType(s, "string"); 143AssertType("hello", "string"); 144 145interface AB<A, B> { 146 a: A; 147 b: B; 148} 149 150type Pair<T> = AB<T, T>; 151 152interface TaggedPair<T> extends Pair<T> { 153 tag: string; 154} 155 156let p: TaggedPair<number>; 157AssertType(p, "TaggedPair<number>"); 158 159p.a = 1; 160AssertType(p.a = 1, "int"); 161AssertType(p.a, "number"); 162AssertType(1, "int"); 163 164p.b = 2; 165AssertType(p.b = 2, "int"); 166AssertType(p.b, "number"); 167AssertType(2, "int"); 168 169p.tag = "test"; 170AssertType(p.tag = "test", "string"); 171AssertType(p.tag, "string"); 172AssertType("test", "string"); 173 174function f<A>() { 175 type Foo<T> = T | { x: Foo<T> }; 176AssertType(Foo, "union"); 177AssertType(x, "union"); 178 179 let x: Foo<A[]>; 180AssertType(x, "union"); 181 182AssertType(x, "union"); 183 return x; 184} 185 186function g<B>() { 187 type Bar<U> = U | { x: Bar<U> }; 188AssertType(Bar, "union"); 189AssertType(x, "union"); 190 191 let x: Bar<B[]>; 192AssertType(x, "union"); 193 194AssertType(x, "union"); 195 return x; 196} 197 198// Deeply instantiated generics 199let a = f<string>(); 200AssertType(a, "union"); 201AssertType(f<string>(), "union"); 202AssertType(f, "<A>() => union"); 203 204let b = g<string>(); 205AssertType(b, "union"); 206AssertType(g<string>(), "union"); 207AssertType(g, "<B>() => union"); 208 209a = b; 210AssertType(a = b, "union"); 211AssertType(a, "union"); 212AssertType(b, "union"); 213 214 215