13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_cilet obj = {n: 42, s: 'foo'} // OK in TypeScript, CTE in ArkTS: unknown type of obj.
173af6ab5fSopenharmony_ci
183af6ab5fSopenharmony_ciclass C {
193af6ab5fSopenharmony_ci  n: number = 0;
203af6ab5fSopenharmony_ci  s: string = "";
213af6ab5fSopenharmony_ci}
223af6ab5fSopenharmony_ci
233af6ab5fSopenharmony_cilet c1: C = {n: 42, s: 'foo'} // Declaration + initialization: type of the literla is inferred from the type of c1.
243af6ab5fSopenharmony_ci
253af6ab5fSopenharmony_cilet c2: C;
263af6ab5fSopenharmony_cic2 = {n: 42, s: 'foo'}; // Initialization after declaration: type of the literal is inferred from the type of c2.
273af6ab5fSopenharmony_ci
283af6ab5fSopenharmony_cilet c3: Object = {n: 42, s: 'foo'} as C as Object; // Type of the literal is inferred from the 'as' cast.
293af6ab5fSopenharmony_ciconsole.log(c3 instanceof C); // NB! Output is true in ArkTS, but is false in TS.
303af6ab5fSopenharmony_ci
313af6ab5fSopenharmony_cifunction foo(c: C) {
323af6ab5fSopenharmony_ci  console.log('foo is called');
333af6ab5fSopenharmony_ci}
343af6ab5fSopenharmony_ci
353af6ab5fSopenharmony_cifoo({n: 42, s: 'foo'}); // Parsing as an argument: type of the literal is inferred from the type of parameter 'c'
363af6ab5fSopenharmony_ci
373af6ab5fSopenharmony_cifunction bar(): C {
383af6ab5fSopenharmony_ci  return {n: 42, s: 'foo'}; // Returning from function: type of the literal is inferred from the bar's return type.
393af6ab5fSopenharmony_ci}
403af6ab5fSopenharmony_ci
413af6ab5fSopenharmony_cilet cc: C[] = [{n: 1, s: '1'}, {n: 2, s: '2'}]; // Type of the literal is inferred from the type of the array.
423af6ab5fSopenharmony_ci
433af6ab5fSopenharmony_ciclass D {
443af6ab5fSopenharmony_ci  b: boolean = false;
453af6ab5fSopenharmony_ci  c: C = {n: 0, s: ""};
463af6ab5fSopenharmony_ci}
473af6ab5fSopenharmony_ci
483af6ab5fSopenharmony_cilet d: D = {
493af6ab5fSopenharmony_ci  b: true,
503af6ab5fSopenharmony_ci  c: { // Initialization of a field with a literal: type of the literal is inferred from the definition of class D.
513af6ab5fSopenharmony_ci    n: 42,
523af6ab5fSopenharmony_ci    s: 'foo'
533af6ab5fSopenharmony_ci  }
543af6ab5fSopenharmony_ci}
553af6ab5fSopenharmony_ci
563af6ab5fSopenharmony_ci// Restrictions of classes that can be initialized with literal
573af6ab5fSopenharmony_ci// Default initializable class.
583af6ab5fSopenharmony_ciclass C1 {
593af6ab5fSopenharmony_ci  n: number = 0;
603af6ab5fSopenharmony_ci  s?: string;
613af6ab5fSopenharmony_ci}
623af6ab5fSopenharmony_ci
633af6ab5fSopenharmony_cilet c4: C1 = {n: 42}; // OK in TS, OK in ArkTS, c.s is null
643af6ab5fSopenharmony_ci
653af6ab5fSopenharmony_ciclass C2 {
663af6ab5fSopenharmony_ci  s: string;
673af6ab5fSopenharmony_ci  constructor(s: string) {
683af6ab5fSopenharmony_ci    this.s = "s = " + s;
693af6ab5fSopenharmony_ci  }
703af6ab5fSopenharmony_ci}
713af6ab5fSopenharmony_ci
723af6ab5fSopenharmony_cilet c5: C2 = {s: 'foo'} // OK in TS, CTE in ArkTS
733af6ab5fSopenharmony_ci
743af6ab5fSopenharmony_ci// All class fields are accessible at the point of initialization.
753af6ab5fSopenharmony_ciclass C3 {
763af6ab5fSopenharmony_ci  private n: number = 0;
773af6ab5fSopenharmony_ci  public s: string = '';
783af6ab5fSopenharmony_ci}
793af6ab5fSopenharmony_ci
803af6ab5fSopenharmony_ci// CTE in TypeScript, CTE in ArkTS // let c6: C3 = {n: 42, s: 'foo'},
813af6ab5fSopenharmony_ci
823af6ab5fSopenharmony_ciclass C4 {
833af6ab5fSopenharmony_ci  readonly n: number = 0;
843af6ab5fSopenharmony_ci  readonly s: string = '';
853af6ab5fSopenharmony_ci}
863af6ab5fSopenharmony_ci
873af6ab5fSopenharmony_cilet c7: C4 = {n: 42, s: 'foo'}; // OK in TS, CTE in ArkTS
883af6ab5fSopenharmony_ci
893af6ab5fSopenharmony_ci// Class is non-abstract
903af6ab5fSopenharmony_ciabstract class A {}
913af6ab5fSopenharmony_cilet a: A = {}; // OK in TS, CTE in ArkTS
923af6ab5fSopenharmony_ci
933af6ab5fSopenharmony_ci// Class declares no methods, apart from optionally declared constructors and setters.
943af6ab5fSopenharmony_ciclass C5 {
953af6ab5fSopenharmony_ci  n: number = 0;
963af6ab5fSopenharmony_ci  s: string = '';
973af6ab5fSopenharmony_ci  f() {
983af6ab5fSopenharmony_ci    console.log('C5.f is called');
993af6ab5fSopenharmony_ci  }
1003af6ab5fSopenharmony_ci}
1013af6ab5fSopenharmony_ci
1023af6ab5fSopenharmony_cilet c8: C5 = {n: 42, s: 'foo', f: () => {}} // OK in TS, CTE in ArkTS
1033af6ab5fSopenharmony_ci
1043af6ab5fSopenharmony_ci// NB! If a class has getters/setters the semantics of initialization differs:
1053af6ab5fSopenharmony_ciclass C6 {
1063af6ab5fSopenharmony_ci  n: number = 0;
1073af6ab5fSopenharmony_ci  _s: string = '';
1083af6ab5fSopenharmony_ci  get s(): string { return this._s; }
1093af6ab5fSopenharmony_ci  set s(s: string) { this._s = s; }
1103af6ab5fSopenharmony_ci}
1113af6ab5fSopenharmony_ci
1123af6ab5fSopenharmony_cilet c9: C6 = {n: 42, _s: 'foo', s: 'bar'}
1133af6ab5fSopenharmony_ciconsole.log(c9.s); // TS: 'bar', ArkTS: 'bar'
1143af6ab5fSopenharmony_ciconsole.log(c9._s); // TS: 'foo', ArkTS: 'bar'
1153af6ab5fSopenharmony_ci
1163af6ab5fSopenharmony_ci// Extra fields are not allowed (eventually it means that it's not possible to assign literals to Object / object):
1173af6ab5fSopenharmony_ciclass C7 {
1183af6ab5fSopenharmony_ci  n: number = 0;
1193af6ab5fSopenharmony_ci  s: string = '';
1203af6ab5fSopenharmony_ci}
1213af6ab5fSopenharmony_ci// TS: CTE, ArtTS: CTE // let c10: C7 = {n: 42, s: '', extra: true},
1223af6ab5fSopenharmony_cilet o1: Object = {s: '', n: 42} // OK in TS, CTE in ArkTS: no fields 'n' and 's' in Object
1233af6ab5fSopenharmony_cilet o2: object = {n: 42, s: ''} // OK in TS, CTE in ArkTS: no fields 'n' and 's' in object
1243af6ab5fSopenharmony_ci
1253af6ab5fSopenharmony_ci// If initialized class is inherited from another class, the base class must also be literal-initializable,
1263af6ab5fSopenharmony_ci// and initialization should happen from the 'glattened' literal:
1273af6ab5fSopenharmony_ciclass Base {
1283af6ab5fSopenharmony_ci  n: number = 0;
1293af6ab5fSopenharmony_ci}
1303af6ab5fSopenharmony_ci
1313af6ab5fSopenharmony_ciclass Derived extends Base {
1323af6ab5fSopenharmony_ci  s: string = '';
1333af6ab5fSopenharmony_ci}
1343af6ab5fSopenharmony_ci
1353af6ab5fSopenharmony_cilet d2: Derived = {n: 42, s: ''};
1363af6ab5fSopenharmony_ci
1373af6ab5fSopenharmony_ci// Interface should not declare methods, only properties are allowed. 
1383af6ab5fSopenharmony_ciinterface I {
1393af6ab5fSopenharmony_ci  n: number;
1403af6ab5fSopenharmony_ci  s: string;
1413af6ab5fSopenharmony_ci  f(): void;
1423af6ab5fSopenharmony_ci}
1433af6ab5fSopenharmony_ci
1443af6ab5fSopenharmony_cilet i: I = {n: 42, s: '', f: () => {console.log('I.f is called')}} // OK in TypeScript, CTE in ArkTS
1453af6ab5fSopenharmony_ci
1463af6ab5fSopenharmony_ci// Interface properties of reference types must be default-initializable:
1473af6ab5fSopenharmony_ciinterface I2 {
1483af6ab5fSopenharmony_ci  n: number;
1493af6ab5fSopenharmony_ci  s: string; // Assuming that 'string' is an alias for 'String', and there is String() constructor (what is true).
1503af6ab5fSopenharmony_ci}
1513af6ab5fSopenharmony_ci
1523af6ab5fSopenharmony_cilet i2: I2 = {n: 42, s: ''};
1533af6ab5fSopenharmony_ci
1543af6ab5fSopenharmony_ciinterface CompilerOptions {
1553af6ab5fSopenharmony_ci  strict?: boolean;
1563af6ab5fSopenharmony_ci  sourcePath?: string;
1573af6ab5fSopenharmony_ci  targetPath?: string;
1583af6ab5fSopenharmony_ci}
1593af6ab5fSopenharmony_ci
1603af6ab5fSopenharmony_ciconst options: CompilerOptions = { // OK, as 'targetPath' field is optional
1613af6ab5fSopenharmony_ci  strict: true,
1623af6ab5fSopenharmony_ci  sourcePath: './src',
1633af6ab5fSopenharmony_ci};
1643af6ab5fSopenharmony_ci
1653af6ab5fSopenharmony_ci// Function parameter with union type. 
1663af6ab5fSopenharmony_cifunction funcWithUnionParam(x: C | number): void { }
1673af6ab5fSopenharmony_cifuncWithUnionParam({ n: 1, s: '2' }) // OK, union type is supported
1683af6ab5fSopenharmony_ci
1693af6ab5fSopenharmony_ci// issue 13022: property with union type
1703af6ab5fSopenharmony_ciclass UnionProperty {
1713af6ab5fSopenharmony_ci    a: number | string = 123;
1723af6ab5fSopenharmony_ci    b?: boolean | number;
1733af6ab5fSopenharmony_ci}
1743af6ab5fSopenharmony_cilet u: UnionProperty = { a: 1 }; // OK, union type is supported
1753af6ab5fSopenharmony_ciu = { a: '2' }; // OK, union type is supported
1763af6ab5fSopenharmony_ciu = { a: 3, b: true }; // OK, union type is supported
1773af6ab5fSopenharmony_ci
1783af6ab5fSopenharmony_ci// issue 13022: optional property
1793af6ab5fSopenharmony_ciclass OptionalProp {
1803af6ab5fSopenharmony_ci  a?: number;
1813af6ab5fSopenharmony_ci}
1823af6ab5fSopenharmony_cilet o: OptionalProp = {};
1833af6ab5fSopenharmony_cio = {a: 1}; // OK
1843af6ab5fSopenharmony_ci
1853af6ab5fSopenharmony_ciclass OptionalProp2 {
1863af6ab5fSopenharmony_ci    a?: number;
1873af6ab5fSopenharmony_ci    b: string;
1883af6ab5fSopenharmony_ci}
1893af6ab5fSopenharmony_cifunction optProp(a: OptionalProp2) {}
1903af6ab5fSopenharmony_cioptProp({b: ''}); // OK
1913af6ab5fSopenharmony_cioptProp({a: 0, b: '1'}); // OK
1923af6ab5fSopenharmony_ci
1933af6ab5fSopenharmony_ci// Property with inheritance
1943af6ab5fSopenharmony_ciclass E1 {
1953af6ab5fSopenharmony_ci  x: number;
1963af6ab5fSopenharmony_ci  y: Base;
1973af6ab5fSopenharmony_ci}
1983af6ab5fSopenharmony_cilet e1 : E1 = {
1993af6ab5fSopenharmony_ci  x: 1,
2003af6ab5fSopenharmony_ci  y: new Derived()
2013af6ab5fSopenharmony_ci}
2023af6ab5fSopenharmony_ci
2033af6ab5fSopenharmony_ci// Property with inheritance through generic type parameter
2043af6ab5fSopenharmony_ciclass E2<T> {
2053af6ab5fSopenharmony_ci  x: number;
2063af6ab5fSopenharmony_ci  y: T;
2073af6ab5fSopenharmony_ci}
2083af6ab5fSopenharmony_cilet e2 : E2<Base> = {
2093af6ab5fSopenharmony_ci  x: 1,
2103af6ab5fSopenharmony_ci  y: new Derived()
2113af6ab5fSopenharmony_ci}
2123af6ab5fSopenharmony_ci
2133af6ab5fSopenharmony_ci// Type alias chain to interface
2143af6ab5fSopenharmony_ciinterface ITypeAlias<T> { a: number; b: T }
2153af6ab5fSopenharmony_citype ITA<T> = ITypeAlias<T>;
2163af6ab5fSopenharmony_citype ITA2<K> = ITA<K>;
2173af6ab5fSopenharmony_cilet ti: ITA2<string> = { // OK, 'ITA2' is an alias to interface 'ITypeAlias'
2183af6ab5fSopenharmony_ci    a: 12,
2193af6ab5fSopenharmony_ci    b: '34'
2203af6ab5fSopenharmony_ci}
2213af6ab5fSopenharmony_ci
2223af6ab5fSopenharmony_ci// Type alias chain to class
2233af6ab5fSopenharmony_ciclass CTypeAlias<T> {
2243af6ab5fSopenharmony_ci    a: number;
2253af6ab5fSopenharmony_ci    b: T;
2263af6ab5fSopenharmony_ci}
2273af6ab5fSopenharmony_citype CTA<T> = CTypeAlias<T>;
2283af6ab5fSopenharmony_citype CTA2<K> = CTA<K>;
2293af6ab5fSopenharmony_cilet tc: CTA2<string> = { // OK, 'CTA' is an alias to class 'CTypeAlias'
2303af6ab5fSopenharmony_ci    a: 4,
2313af6ab5fSopenharmony_ci    b: '4'
2323af6ab5fSopenharmony_ci}
2333af6ab5fSopenharmony_ci
2343af6ab5fSopenharmony_ci// issue 13114: Const enum value converted to string/number type.
2353af6ab5fSopenharmony_ciconst enum ATTRIBUTE {
2363af6ab5fSopenharmony_ci  ROW = 'Row',
2373af6ab5fSopenharmony_ci  COLUMN = 'Column',
2383af6ab5fSopenharmony_ci  COLUMN_REVERSE = 'ColumnReverse',
2393af6ab5fSopenharmony_ci};
2403af6ab5fSopenharmony_ciconst enum GROUP {
2413af6ab5fSopenharmony_ci  MAIN_DIRECTION = 'MAIN_DIRECTION',
2423af6ab5fSopenharmony_ci};
2433af6ab5fSopenharmony_cienum Orientation {
2443af6ab5fSopenharmony_ci  Horizontal,
2453af6ab5fSopenharmony_ci  Vertical
2463af6ab5fSopenharmony_ci}
2473af6ab5fSopenharmony_ciclass ContainerModuleItem {
2483af6ab5fSopenharmony_ci  groupName: string = '';
2493af6ab5fSopenharmony_ci  attributeList: string[] = [];
2503af6ab5fSopenharmony_ci  attribute: ATTRIBUTE = ATTRIBUTE.COLUMN;
2513af6ab5fSopenharmony_ci  orientation: number = 0;
2523af6ab5fSopenharmony_ci}
2533af6ab5fSopenharmony_ciconst FLEX_MODULE: ContainerModuleItem[] = [
2543af6ab5fSopenharmony_ci  {
2553af6ab5fSopenharmony_ci    groupName: GROUP.MAIN_DIRECTION,
2563af6ab5fSopenharmony_ci    attributeList: [ATTRIBUTE.COLUMN, ATTRIBUTE.ROW, ATTRIBUTE.COLUMN_REVERSE],
2573af6ab5fSopenharmony_ci    attribute: ATTRIBUTE.ROW,
2583af6ab5fSopenharmony_ci    orientation: Orientation.Horizontal
2593af6ab5fSopenharmony_ci  }
2603af6ab5fSopenharmony_ci];
2613af6ab5fSopenharmony_ci
2623af6ab5fSopenharmony_ciinterface I3 {}
2633af6ab5fSopenharmony_ci
2643af6ab5fSopenharmony_ciclass CCl implements I3 {}
2653af6ab5fSopenharmony_ci
2663af6ab5fSopenharmony_ciclass CCl2 extends CCl implements I3 {}
2673af6ab5fSopenharmony_ci
2683af6ab5fSopenharmony_ciinterface I4 {
2693af6ab5fSopenharmony_ci        a: I3;
2703af6ab5fSopenharmony_ci        b: I3;
2713af6ab5fSopenharmony_ci        c: CCl;
2723af6ab5fSopenharmony_ci        d: CCl2;
2733af6ab5fSopenharmony_ci}
2743af6ab5fSopenharmony_ci
2753af6ab5fSopenharmony_ciclass DCl {
2763af6ab5fSopenharmony_ci        constructor(a: I4) {}
2773af6ab5fSopenharmony_ci}
2783af6ab5fSopenharmony_ci
2793af6ab5fSopenharmony_cilet c: I4 = {a: new CCl(), b: new CCl2(), c: new CCl2(), d: new CCl2()}
2803af6ab5fSopenharmony_ci
2813af6ab5fSopenharmony_cinew DCl({a: new CCl(), b: new CCl2(), c: new CCl2(), d: new CCl2()})
2823af6ab5fSopenharmony_ci
2833af6ab5fSopenharmony_cilet oo1: Object = {}
2843af6ab5fSopenharmony_ci
2853af6ab5fSopenharmony_cilet oo2: Object = {a: 12}
286