• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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