1/* 2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16interface GeneratedObjectLiteralInterface_1 { 17 n: number; 18 s: string; 19} 20let obj: GeneratedObjectLiteralInterface_1 = {n: 42, s: 'foo'} // OK in TypeScript, CTE in ArkTS: unknown type of obj. 21 22class C { 23 n: number = 0; 24 s: string = ""; 25} 26 27let c1: C = {n: 42, s: 'foo'} // Declaration + initialization: type of the literla is inferred from the type of c1. 28 29let c2: C; 30c2 = {n: 42, s: 'foo'}; // Initialization after declaration: type of the literal is inferred from the type of c2. 31 32let c3: Object = {n: 42, s: 'foo'} as C as Object; // Type of the literal is inferred from the 'as' cast. 33console.log(c3 instanceof C); // NB! Output is true in ArkTS, but is false in TS. 34 35function foo(c: C) { 36 console.log('foo is called'); 37} 38 39foo({n: 42, s: 'foo'}); // Parsing as an argument: type of the literal is inferred from the type of parameter 'c' 40 41function bar(): C { 42 return {n: 42, s: 'foo'}; // Returning from function: type of the literal is inferred from the bar's return type. 43} 44 45let cc: C[] = [{n: 1, s: '1'}, {n: 2, s: '2'}]; // Type of the literal is inferred from the type of the array. 46 47class D { 48 b: boolean = false; 49 c: C = {n: 0, s: ""}; 50} 51 52let d: D = { 53 b: true, 54 c: { // Initialization of a field with a literal: type of the literal is inferred from the definition of class D. 55 n: 42, 56 s: 'foo' 57 } 58} 59 60// Restrictions of classes that can be initialized with literal 61// Default initializable class. 62class C1 { 63 n: number = 0; 64 s?: string; 65} 66 67let c4: C1 = {n: 42}; // OK in TS, OK in ArkTS, c.s is null 68 69class C2 { 70 s: string; 71 constructor(s: string) { 72 this.s = "s = " + s; 73 } 74} 75 76let c5: C2 = {s: 'foo'} // OK in TS, CTE in ArkTS 77 78// All class fields are accessible at the point of initialization. 79class C3 { 80 private n: number = 0; 81 public s: string = ''; 82} 83 84// CTE in TypeScript, CTE in ArkTS // let c6: C3 = {n: 42, s: 'foo'}, 85 86class C4 { 87 readonly n: number = 0; 88 readonly s: string = ''; 89} 90 91let c7: C4 = {n: 42, s: 'foo'}; // OK in TS, CTE in ArkTS 92 93// Class is non-abstract 94abstract class A {} 95let a: A = {}; // OK in TS, CTE in ArkTS 96 97// Class declares no methods, apart from optionally declared constructors and setters. 98class C5 { 99 n: number = 0; 100 s: string = ''; 101 f() { 102 console.log('C5.f is called'); 103 } 104} 105 106let c8: C5 = {n: 42, s: 'foo', f: () => {}} // OK in TS, CTE in ArkTS 107 108// NB! If a class has getters/setters the semantics of initialization differs: 109class C6 { 110 n: number = 0; 111 _s: string = ''; 112 get s(): string { return this._s; } 113 set s(s: string) { this._s = s; } 114} 115 116let c9: C6 = {n: 42, _s: 'foo', s: 'bar'} 117console.log(c9.s); // TS: 'bar', ArkTS: 'bar' 118console.log(c9._s); // TS: 'foo', ArkTS: 'bar' 119 120// Extra fields are not allowed (eventually it means that it's not possible to assign literals to Object / object): 121class C7 { 122 n: number = 0; 123 s: string = ''; 124} 125// TS: CTE, ArtTS: CTE // let c10: C7 = {n: 42, s: '', extra: true}, 126let o1: Object = {s: '', n: 42} // OK in TS, CTE in ArkTS: no fields 'n' and 's' in Object 127let o2: object = {n: 42, s: ''} // OK in TS, CTE in ArkTS: no fields 'n' and 's' in object 128 129// If initialized class is inherited from another class, the base class must also be literal-initializable, 130// and initialization should happen from the 'glattened' literal: 131class Base { 132 n: number = 0; 133} 134 135class Derived extends Base { 136 s: string = ''; 137} 138 139let d2: Derived = {n: 42, s: ''}; 140 141// Interface should not declare methods, only properties are allowed. 142interface I { 143 n: number; 144 s: string; 145 f(): void; 146} 147 148let i: I = {n: 42, s: '', f: () => {console.log('I.f is called')}} // OK in TypeScript, CTE in ArkTS 149 150// Interface properties of reference types must be default-initializable: 151interface I2 { 152 n: number; 153 s: string; // Assuming that 'string' is an alias for 'String', and there is String() constructor (what is true). 154} 155 156let i2: I2 = {n: 42, s: ''}; 157 158interface CompilerOptions { 159 strict?: boolean; 160 sourcePath?: string; 161 targetPath?: string; 162} 163 164const options: CompilerOptions = { // OK, as 'targetPath' field is optional 165 strict: true, 166 sourcePath: './src', 167}; 168 169// Function parameter with union type. 170function funcWithUnionParam(x: C | number): void { } 171funcWithUnionParam({ n: 1, s: '2' }) // OK, union type is supported 172 173// issue 13022: property with union type 174class UnionProperty { 175 a: number | string = 123; 176 b?: boolean | number; 177} 178let u: UnionProperty = { a: 1 }; // OK, union type is supported 179u = { a: '2' }; // OK, union type is supported 180u = { a: 3, b: true }; // OK, union type is supported 181 182// issue 13022: optional property 183class OptionalProp { 184 a?: number; 185} 186let o: OptionalProp = {}; 187o = {a: 1}; // OK 188 189class OptionalProp2 { 190 a?: number; 191 b: string; 192} 193function optProp(a: OptionalProp2) {} 194optProp({b: ''}); // OK 195optProp({a: 0, b: '1'}); // OK 196 197// Property with inheritance 198class E1 { 199 x: number; 200 y: Base; 201} 202let e1 : E1 = { 203 x: 1, 204 y: new Derived() 205} 206 207// Property with inheritance through generic type parameter 208class E2<T> { 209 x: number; 210 y: T; 211} 212let e2 : E2<Base> = { 213 x: 1, 214 y: new Derived() 215} 216 217// Type alias chain to interface 218interface ITypeAlias<T> { a: number; b: T } 219type ITA<T> = ITypeAlias<T>; 220type ITA2<K> = ITA<K>; 221let ti: ITA2<string> = { // OK, 'ITA2' is an alias to interface 'ITypeAlias' 222 a: 12, 223 b: '34' 224} 225 226// Type alias chain to class 227class CTypeAlias<T> { 228 a: number; 229 b: T; 230} 231type CTA<T> = CTypeAlias<T>; 232type CTA2<K> = CTA<K>; 233let tc: CTA2<string> = { // OK, 'CTA' is an alias to class 'CTypeAlias' 234 a: 4, 235 b: '4' 236} 237 238// issue 13114: Const enum value converted to string/number type. 239const enum ATTRIBUTE { 240 ROW = 'Row', 241 COLUMN = 'Column', 242 COLUMN_REVERSE = 'ColumnReverse', 243}; 244const enum GROUP { 245 MAIN_DIRECTION = 'MAIN_DIRECTION', 246}; 247enum Orientation { 248 Horizontal, 249 Vertical 250} 251class ContainerModuleItem { 252 groupName: string = ''; 253 attributeList: string[] = []; 254 attribute: ATTRIBUTE = ATTRIBUTE.COLUMN; 255 orientation: number = 0; 256} 257const FLEX_MODULE: ContainerModuleItem[] = [ 258 { 259 groupName: GROUP.MAIN_DIRECTION, 260 attributeList: [ATTRIBUTE.COLUMN, ATTRIBUTE.ROW, ATTRIBUTE.COLUMN_REVERSE], 261 attribute: ATTRIBUTE.ROW, 262 orientation: Orientation.Horizontal 263 } 264]; 265 266interface I3 {} 267 268class CCl implements I3 {} 269 270class CCl2 extends CCl implements I3 {} 271 272interface I4 { 273 a: I3; 274 b: I3; 275 c: CCl; 276 d: CCl2; 277} 278 279class DCl { 280 constructor(a: I4) {} 281} 282 283let c: I4 = {a: new CCl(), b: new CCl2(), c: new CCl2(), d: new CCl2()} 284 285new DCl({a: new CCl(), b: new CCl2(), c: new CCl2(), d: new CCl2()}) 286 287let oo1: Object = {} 288 289let oo2: Object = {a: 12} 290