• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Introduction
2
3<!--Kit: ArkTS-->
4<!--Subsystem: ArkCompiler-->
5<!--Owner: @LeechyLiang-->
6<!--Designer: @qyhuo32-->
7<!--Tester: @kirl75; @zsw_zhushiwei-->
8<!--Adviser: @zhang_yixin13-->
9
10Welcome to the tutorial for ArkTS, a TypeScript-based programming language designed specifically to build high-performance mobile applications! ArkTS is optimized to provide better performance and efficiency, while still maintaining the familiar syntax of TypeScript.
11
12Many current programming languages were not designed with mobile devices in mind, resulting in slow and inefficient applications that drain battery life. As mobile devices continue to become more prevalent in our daily lives, there is a growing need for programming languages optimized for the mobile environment. ArkTS has been specifically designed to address such concerns by prioritizing higher execution efficiency.
13
14ArkTS is based on the popular programming language TypeScript that extends JavaScript by adding type definitions. TypeScript is well-loved by many developers as it provides a more structured approach to coding in JavaScript. ArkTS aims to keep the look and feel of TypeScript to enable a seamless transition for the existing TypeScript developers, and to let mobile developers learn ArkTS quickly.
15
16One of the key features of ArkTS is its focus on low runtime overhead. ArkTS imposes stricter limitations on the TypeScript's dynamically typed features, reducing runtime overhead and allowing faster execution. By eliminating the dynamically typed features from the language, ArkTS code can be compiled ahead-of-time more efficiently, resulting in faster application startup and lower power consumption.
17
18Interoperability with TypeScript and JavaScript was a critical consideration in the ArkTS language design. Many mobile application developers already have TypeScript and JavaScript code and libraries they would want to reuse. ArkTS has been designed for seamless JavaScript interoperability, making it easy for the developers to integrate the JavaScript code into their applications and vice versa. This will allow the developers to use their existing codebases and libraries to leverage the power of our new language.
19
20This tutorial will guide you through the core features, syntax, and best practices of ArkTS. After reading this tutorial through the end, you will be able to build performant and efficient mobile applications in ArkTS.
21
22For a more detailed understanding of the ArkTS language, see [Introduction to ArkTS](../arkts-utils/arkts-overview.md)<!--RP1--><!--RP1End-->.
23
24## The Basics
25
26### Declarations
27
28Declarations in ArkTS allow you to introduce variables, constants, types, and functions.
29
30**Variable declaration**
31
32A declaration starting with the keyword `let` introduces a variable which can have different values during program execution.
33
34```typescript
35let hi: string = 'hello';
36hi = 'hello, world';
37```
38
39**Constant declaration**
40
41A declaration starting with the keyword `const` introduces a read-only constant that can be assigned only once.
42
43```typescript
44const hello: string = 'hello';
45```
46
47A compile-time error occurs if a new value is assigned to a constant.
48
49**Automatic type inference**
50
51You do not need to explicitly specify the type of a declared entity if a variable or a constant declaration contains an initial value, as all cases that allow the type to be inferred automatically are specified in the ArkTS Specification.
52
53Both variable declarations are valid, and both variables are of the `string` type:
54
55```typescript
56let hi1: string = 'hello';
57let hi2 = 'hello, world';
58```
59
60### Types
61
62**Basic types and reference types**
63
64Basic types include number and string, which can accurately represent simple data types. You can directly store and access these types and compare their values.
65
66Reference types include complex data structures such as objects, arrays, and functions. These types access data by reference. An object and array contain multiple values or KV pairs, and a function encapsulates executable code logic. The reference type accesses data in the memory through pointers. Changing the reference affects the original data.
67
68**`number` type**
69
70ArkTS has the number type. Any integer and floating-point values can be assigned to a variable of this type.
71
72Numeric literals include integer literals and floating-point literals with the decimal base.
73
74Integer literals are classified into the following:
75
76* Decimal integers consist of digit sequences.* Decimal integers that consist of a sequence of digits. Example: `0`, `117`, `-345`.
77* Hexadecimal integers that start with 0x (or 0X), and can contain digits (0-9) and letters a-f or A-F. Example: `0x1123`, `0x00111`, `-0xF1A7`.
78* Octal integers that start with 0o (or 0O) and can only contain digits (0-7). Example: `0o777`.
79* Binary integers that start with 0b (or 0B), and can only contain the digits 0 and 1. Example: `0b11`, `0b0011`, `-0b11`.
80
81A floating-point literal includes the following:
82
83* Decimal integer, optionally signed (that is, prefixed with "+" or "-")
84* Decimal point (".")
85* Fractional part (represented by a string of decimal digits)
86* Exponent part that starts with "e" or "E", followed by an optionally signed (that is, prefixed with "+" or "-") integer
87
88Example:
89
90```typescript
91let n1 = 3.14;
92let n2 = 3.141592;
93let n3 = .5;
94let n4 = 1e2;
95
96function factorial(n: number): number {
97  if (n <= 1) {
98    return 1;
99  }
100  return n * factorial(n - 1);
101}
102
103factorial(n1)  //  7.660344000000002
104factorial(n2)  //  7.680640444893748
105factorial(n3)  //  1
106factorial(n4)  //  9.33262154439441e+157
107```
108
109The `number` type tends to lose precision when it represents very large integers (ranging from -9007199254740991 to 9007199254740991). You can use the `bigint` type to ensure the precision as required.
110
111```typescript
112
113let bigInt: BigInt = BigInt('999999999999999999999999999999999999999999999999999999999999');
114console.info('bigInt:' + bigInt.toString());
115
116```
117
118**`boolean` type**
119
120The `boolean` type represents logical values that are either `true` or `false`.
121
122Usually variables of this type are used in conditional statements:
123
124```typescript
125let isDone: boolean = false;
126
127// ...
128
129if (isDone) {
130  console.info('Done!');
131}
132```
133
134**`string` type**
135
136A `string` is a sequence of characters; some characters can be set by using escape sequences.
137
138A `string` literal consists of zero or more characters enclosed in single (') or double quotes ("). The special form of a string literal is the template literal enclosed in backticks (\`).
139
140```typescript
141let s1 = 'Hello, world!\n';
142let s2 = "this is a string";
143let a = 'Success';
144let s3 = `The result is ${a}`;
145```
146
147**`void` type**
148
149The `void` type is used to specify that a function does not return a value.
150This type has the only one value which is also `void`. As `void` is a reference type, it can be used as type argument for generic types.
151
152```typescript
153class Class<T> {
154  //...
155}
156let instance: Class <void>
157```
158
159**`Object` type**
160
161An `Object` class type is a base type for all reference types. Any value, including values of primitive types (they will be automatically boxed), can be directly assigned to variables of the type `Object`. The `Object` type is used to represent types other than the primitive types.
162```typescript
163let o1: Object = 'Alice';
164let o2: Object = ['a','b'];
165let o3: Object = 1;
166```
167
168**`array` type**
169
170An `array` is an object comprised of elements of data types assignable to the element type specified in the array declaration.
171A value of an array is set by using array composite literal, which is a list of zero or more expressions enclosed in square brackets ([]). Each expression represents an element of the array. The length of the array is set by the number of expressions. Index of the first array element is 0.
172
173The following example creates the array with three elements:
174
175```typescript
176let names: string[] = ['Alice', 'Bob', 'Carol'];
177```
178
179**`enum` type**
180
181An `enum` type is a value type with a defined set of named values called enum constants.
182In order to be used, an enum constant must be prefixed with an enum type name.
183
184```typescript
185enum ColorSet { Red, Green, Blue }
186let c: ColorSet = ColorSet.Red;
187```
188
189A constant expression can be used to explicitly set the value of an enum constant.
190
191```typescript
192enum ColorSet { White = 0xFF, Grey = 0x7F, Black = 0x00 }
193let c: ColorSet = ColorSet.Black;
194```
195
196**`Union` type**
197
198A `Union` type is a reference type which is created as a combination of multiple types. Values of union types can be valid values of all types a union was created from.
199
200```typescript
201class Cat {
202  name: string = 'cat';
203  // ...
204}
205class Dog {
206  name: string = 'dog';
207  // ...
208}
209class Frog {
210  name: string = 'frog';
211  // ...
212}
213type Animal = Cat | Dog | Frog | number | string | null | undefined;
214// Cat, Dog, and Frog are some types (classes or interfaces).
215
216let animal: Animal = new Cat();
217animal = new Frog();
218animal = 42;
219animal = 'dog';
220animal = undefined;
221// One may assign the variable of the union type with any valid value.
222```
223
224There are different mechanisms to get a value of a particular type from a union.
225
226Example:
227
228```typescript
229class Cat { sleep () {}; meow () {} }
230class Dog { sleep () {}; bark () {} }
231class Frog { sleep () {}; leap () {} }
232
233type Animal = Cat | Dog | Frog;
234
235function foo(animal: Animal) {
236  if (animal instanceof Frog) {
237    animal.leap(); // animal is of type Frog here.
238  }
239  animal.sleep(); // Any animal can sleep.
240}
241```
242
243**`Aliases` type**
244
245Type `Aliases` provides names for anonymous types (such as array, function, object literal or union type) or alternative names for existing types.
246
247```typescript
248type Matrix = number[][];
249type Handler = (s: string, no: number) => string;
250type Predicate <T> = (x: T) => boolean;
251type NullableObject = Object | null;
252```
253
254### Operators
255
256Assignment operators
257
258Simple assignment operator `=` is used as in `x = y`.
259
260Compound assignment operators combine an assignment with an operator. For example, `a += b` equals `a = a + b`,
261
262where `+=` is a compound assignment operator.
263
264Compound assignment operators are as follows: `+=`, `-=`, `*=`, `/=`, `%=`, `<<=`, `>>=`, `>>>=`, `&=`, `|=`, and `^=`.
265
266**Comparison operators**
267
268| Operator| Description                                                |
269| -------- | ------------------------------------------------------------ |
270| `===`    | Returns **true** if both operands are strict equal. (Operands of different types, such as string and number, are considered unequal.)|
271| `!==`    | Returns **true** if both operands are not strict equal. (Operands of different types, such as string and number, are considered unequal.)|
272| `==`     | Returns **true** if both operands are equal.|
273| `!=`     | Returns **true** if both operands are not equal.   |
274| `>`      | Returns **true** if the left operand is greater than the right.|
275| `>=`     | Returns **true** if the left operand is greater than or equal to the right.|
276| `<`      | Returns **true** if the left operand is less than the right.   |
277| `<=`     | Returns **true** if the left operand is less than or equal to the right.|
278
279The differences between `===` and `==` are as follows:
280```typescript
281    let a:Object=1;
282    let b:Object='1';
283    // == compares only the values.
284    console.info(a == b); // true
285    // === compares the values and types.
286    console.info(a === b); // false
287```
288
289
290**Arithmetic operators**
291
292Unary operators are as follows: `-`, `+`, `--`, and `++`.
293
294Binary operators are as follows:
295
296| Operator| Description            |
297| -------- | ------------------------ |
298| `+`      | Addition               |
299| `-`      | Subtraction            |
300| `*`      | Multiplication         |
301| `/`      | Division               |
302| `%`      | Remainder after division|
303
304**Bitwise operators**
305
306| Operator| Description                                                |
307| --------- | ------------------------------------------------------------ |
308| `a & b`   | Bitwise AND: sets each bit to 1 if the corresponding bits of both operands are 1, otherwise to 0.|
309| `a | b`  | Bitwise OR: sets each bit to 1 if at least one of the corresponding bits of both operands is 1, otherwise to 0.|
310| `a ^ b`   | Bitwise XOR: sets each bit to 1 if the corresponding bits of both operands are different, otherwise to 0.|
311| `~ a`     | Bitwise NOT: inverts the bits of the operand.              |
312| `a << b`  | Shift left: shifts the binary representation of *a* to the left by *b* bits.|
313| `a >> b`  | Arithmetic right shift: shifts the binary representation of *a* to the right by *b* bits with sign-extension.|
314| `a >>> b` | Logical right shift: shifts the binary representation of *a* to the right by *b* bits with zero-extension.|
315
316**Logical operators**
317
318| Operator | Description|
319| ---------- | ----------- |
320| `a && b`   | Logical AND|
321| `a || b` | Logical OR|
322| `! a`      | Logical NOT|
323
324### Statements
325
326**`If` statement**
327
328An `if` statement is used to execute a sequence of statements when a logical condition is true, or another set of statements (if provided) otherwise.
329The `else` part can also contain more `if` statements.
330
331An `if` statement is as follows:
332
333```typescript
334if (condition1) {
335  // Statement 1
336} else if (condition2) {
337  // Statement 2
338} else {
339  // The else statement
340}
341```
342
343All conditional expressions must be of any type. For types other than `boolean`, implicit conversion rules are applied:
344
345```typescript
346let s1 = 'Hello';
347if (s1) {
348  console.info(s1); // Print "Hello"
349}
350
351let s2 = 'World';
352if (s2.length != 0) {
353  console.info(s2); // Print "World"
354}
355```
356
357**`Switch` statement**
358
359A `switch` statement is used to execute a sequence of statements that match the value of a `switch` expression.
360
361The **switch** statement is as follows:
362
363```typescript
364switch (expression) {
365  case label1: // Execute if label1 is matched.
366    // ...
367    // Statement 1
368    // ...
369    break; // Can be omitted.
370  case label2:
371  case label3: // Execute if label2 or label3 is matched.
372    // ...
373    // Statement 23
374    // ...
375    break; // Can be omitted.
376  default:
377    // Default statement
378}
379```
380
381If the value of a `switch` expression equals the value of some label, then the corresponding statements are executed.
382
383If there is no match, and the `switch` has the `default` clause, then the `default` statements are executed.
384
385An optional `break` statement allows you to break out of the `switch` and continue executing the statement that follows the `switch`.
386
387If there is no `break`, then the next statements in the `switch` are executed.
388
389**Conditional expressions**
390
391A conditional expression returns the result of one of the other two expressions based on the Boolean value of the first expression.
392
393A conditional expression looks as follows:
394
395```typescript
396condition ? expression1 : expression2
397```
398
399If the value of `condition` is truthy (a value that is considered `true`), the `expression1` is used as the result of the expression; otherwise, the `expression2` is used.
400
401Example:
402
403```typescript
404let message = Math.random() > 0.5 ? 'Valid' : 'Failed';
405```
406
407If the value of `condition` is not a Boolean value, implicit conversion is performed.
408
409Example:
410
411```typescript
412    console.info('a' ? 'true' : 'false'); // true
413    console.info('' ? 'true' : 'false'); // false
414    console.info(1 ? 'true' : 'false'); // true
415    console.info(0 ? 'true' : 'false'); // false
416    console.info(null ? 'true' : 'false'); // false
417    console.info(undefined ? 'true' : 'false'); // false
418```
419
420**`For` statement**
421
422The `for` statement is executed repeatedly until the specified loop exit condition result is `false`.
423
424The `for` statement is as follows:
425
426```typescript
427for ([init]; [condition]; [update]) {
428  statements
429}
430```
431
432When a `for` statement is executed, the following process takes place:
433
4341. An `init` expression is executed, if any. This expression usually initializes one or more loop counters.
4352. The `condition` is evaluated. If the value of `condition` is truthy (a value that is considered `true`), or if the conditional expression is omitted, the statements in the `for` body are to be executed. If the value of `condition` is falsy (a value that is considered `false`), the `for` loop terminates.
4363. The statements of the `for` body are executed.
4374. If there is an `update` expression, then the `update` expression is executed.
4385. Go back to step 2.
439
440Example:
441
442```typescript
443let sum = 0;
444for (let i = 0; i < 10; i += 2) {
445  sum += i;
446}
447```
448
449**`For-of` statement**
450
451You can use the `for-of` statement to iterate over iterable types such as array, Set, Map, and string. A `for-of` statement looks as follows:
452
453```typescript
454for (forVar of IterableExpression) {
455  // process forVar
456}
457```
458
459Example:
460
461```typescript
462for (let ch of 'a string object') {
463  console.info(ch);
464}
465```
466
467**`While` statement**
468
469The `while` statement executes `statements` as long as the value of `condition` is `true`. A `while` statement looks as follows:
470
471```typescript
472while (condition) {
473  statements
474}
475```
476
477Example:
478
479```typescript
480let n = 0;
481let x = 0;
482while (n < 3) {
483  n++;
484  x += n;
485}
486```
487
488**`Do-while` statement**
489
490If the value of `condition` is truthy (a value that is considered `true`), the `statements` is executed repeatedly. A `do-while` statement looks as follows:
491
492```typescript
493do {
494  statements
495} while (condition)
496```
497
498Example:
499
500```typescript
501let i = 0;
502do {
503  i += 1;
504} while (i < 10)
505```
506
507**`Break` statement**
508
509A `break` statement is used to terminate any `loop` statement or `switch`.
510
511A `break` statement looks as follows:
512
513```typescript
514let x = 0;
515while (true) {
516  x++;
517  if (x > 5) {
518    break;
519  }
520}
521```
522
523A `break` statement with a label identifier transfers control out of the enclosing statement to the one which has the same label identifier.
524
525Example:
526
527```typescript
528let x = 1;
529label: while (true) {
530  switch (x) {
531    case 1:
532      // statements
533      break label; // Break the while statement.
534  }
535}
536```
537
538**`Continue` statement**
539
540A `continue` statement stops the execution of the current loop iteration and passes control to the next iteration.
541
542Example:
543
544```typescript
545let sum = 0;
546for (let x = 0; x < 100; x++) {
547  if (x % 2 == 0) {
548    continue;
549  }
550  sum += x;
551}
552```
553
554**`Throw` and `Try` statements**
555
556A `throw` statement is used to throw an exception or an error:
557
558```typescript
559throw new Error('this error')
560```
561
562A `try` statement is used to catch and handle an exception or an error:
563
564```typescript
565try {
566  // Statement block where an exception may occur
567} catch (e) {
568  // Handle the exception.
569}
570```
571
572The example below shows the `throw` and `try` statements used to handle the zero division case:
573
574```typescript
575class ZeroDivisor extends Error {}
576
577function divide (a: number, b: number): number{
578  if (b == 0) throw new ZeroDivisor();
579  return a / b;
580}
581
582function process (a: number, b: number) {
583  try {
584    let res = divide(a, b);
585    console.info('result: ' + res);
586  } catch (x) {
587    console.error('some error');
588  }
589}
590```
591
592`finally` clause is also supported:
593
594```typescript
595function processData(s: string) {
596  let error: Error | null = null;
597
598  try {
599    console.info('Data processed: ' + s);
600    // ...
601    // Statement where an exception may occur
602    // ...
603  } catch (e) {
604    error = e as Error;
605    // ...
606    // Handle the exception.
607    // ...
608  } finally {
609    // Code that is executed regardless of whether an exception occurs
610    if (error != null) {
611      console.error(`Error caught: input='${s}', message='${error.message}'`);
612    }
613  }
614}
615```
616
617## Function
618
619### Function Declaration
620
621A function declaration introduces a named function, specifying its name, parameters, return type and body.
622
623Below is a simple function with two string parameters and string return type:
624
6251. Parameter type annotation: **x: string, y: string** explicitly specifies the parameter type as string.
626
6272. Return value type: **: string** specifies the return value type of the function as string.
628
629```typescript
630function add(x: string, y: string): string {
631  let z: string = `${x} ${y}`;
632  return z;
633}
634```
635
636For every parameter, its type annotation must be specified. An optional parameter allows you to omit this parameter when calling a function. The last parameter of a function can be a rest parameter.
637
638### Optional Parameter
639
640The format of the optional parameter can be `name?: Type`.
641
642```typescript
643function hello(name?: string) {
644  if (name == undefined) {
645    console.info('Hello!');
646  } else {
647    console.info(`Hello, ${name}!`);
648  }
649}
650```
651
652Another form contains an expression that specifies a default value. If the optional parameter is omitted in a function call, the default value of the parameter is used as the argument.
653
654```typescript
655function multiply(n: number, coeff: number = 2): number {
656  return n * coeff;
657}
658multiply(2);  // Return 2*2.
659multiply(2, 3); // Return 2*3.
660```
661
662### Rest Parameter
663
664The last parameter of a function can be a rest parameter in the format of `...restArgs`. It allows functions to take unlimited number of arguments of any specified type.
665
666```typescript
667function sum(...numbers: number[]): number {
668  let res = 0;
669  for (let n of numbers)
670    res += n;
671  return res;
672}
673
674sum(); // Return 0.
675sum(1, 2, 3); // Return 6.
676```
677
678### Return Type
679
680If function return type can be inferred from its body content, then it can be omitted from the function declaration.
681
682```typescript
683// Explicit return type
684function foo(): string { return 'foo'; }
685
686// Implicit return type inferred as string
687function goo() { return 'goo'; }
688```
689
690The return type of a function that does not need to return a value can be explicitly specified as `void` or omitted altogether. No return statement is needed for such functions.
691
692Both notations below are valid:
693
694```typescript
695function hi1() { console.info('hi'); }
696function hi2(): void { console.info('hi'); }
697```
698
699### Function Scope
700
701Variables and other entities defined in a function are local to the function and cannot be accessed from the outside.
702
703If the name of a variable defined in the function is equal to the name of an entity in the outer scope, then the local definition shadows the outer entity.
704
705```typescript
706let outerVar = 'I am outer ';
707
708function func() {
709    let outerVar = 'I am inside';
710    console.info(outerVar); // Output: I am inside
711}
712
713func();
714```
715
716### Function Call
717
718Calling a function actually leads to the execution of its body, while the arguments of the call are assigned to the function parameters.
719
720If the function is defined as follows:
721
722```typescript
723function join(x: string, y: string): string {
724  let z: string = `${x} ${y}`;
725  return z;
726}
727```
728
729Then this function is called with two parameters of the type `string`:
730
731```typescript
732let x = join('hello', 'world');
733console.info(x); // Output: hello world
734```
735
736### Function Type
737
738A Function type is commonly used as follows to define a callback:
739
740```typescript
741type trigFunc = (x: number) => number // This is a function type.
742
743function do_action(f: trigFunc) {
744  f(3.141592653589); // Call the function.
745}
746
747do_action(Math.sin); // Pass in the function as a parameter.
748```
749
750### Arrow Function (Lambda Function)
751
752A function can be defined as an arrow function. Example:
753
754```typescript
755let sum = (x: number, y: number): number => {
756  return x + y;
757}
758```
759
760An arrow function return type can be omitted; in such case, it is inferred from the function body.
761
762An expression can be specified as an arrow function to make the notation shorter, that is, the following two notations are equivalent:
763
764```typescript
765let sum1 = (x: number, y: number) => { return x + y; }
766let sum2 = (x: number, y: number) => x + y
767```
768
769### Closure
770
771A closure is the combination of a function and the lexical environment within which that function was declared. This environment consists of any local variables that were in-scope at the time the closure was created.
772
773In the following example, the `f` function returns a closure that captures the `count` variable. Each time `z` is called, the value of `count` is retained and incremented.
774
775```typescript
776function f(): () => number {
777  let count = 0;
778  let g = (): number => { count++; return count; };
779  return g;
780}
781
782let z = f();
783z(); // Return 1.
784z(); // Return 2.
785```
786
787### Function Overload Signature
788
789A function can be specified to be called in different ways by writing overload signatures. To do so, several functions' headers that have the same name but different signatures are written to the same function and immediately followed by the single implementation function.
790
791```typescript
792function foo(x: number): void;            /* First function definition */
793function foo(x: string): void;            /* Second function definition */
794function foo(x: number | string): void {  /* Implementation signature */
795}
796
797foo(123);     // Use the first function definition.
798foo('aa'); // Use the second function definition.
799```
800
801An error occurs if two overload signatures have identical names and parameter lists.
802
803## Class
804
805A class declaration introduces a new type and defines its fields, methods and constructors.
806
807In the following example, class `Person` is defined, which has fields **name** and **surname**, constructor, and the `fullName` method:
808
809```typescript
810class Person {
811  name: string = '';
812  surname: string = '';
813  constructor (n: string, sn: string) {
814    this.name = n;
815    this.surname = sn;
816  }
817  fullName(): string {
818    return this.name + ' ' + this.surname;
819  }
820}
821```
822
823After the class is defined, its instances can be created by using the keyword `new`:
824
825```typescript
826let p = new Person('John', 'Smith');
827console.info(p.fullName());
828```
829
830Alternatively, an instance can be created by using object literals:
831
832```typescript
833class Point {
834  x: number = 0;
835  y: number = 0;
836}
837let p: Point = {x: 42, y: 42};
838```
839
840### Field
841
842A field is a variable of some type that is declared directly in a class.
843
844Classes may have instance fields or static fields.
845
846**Instance fields**
847
848Instance fields exist on every instance of a class. Each instance has its own set of instance fields.
849
850An instance of the class is used to access an instance field.
851
852```typescript
853class Person {
854  name: string = '';
855  age: number = 0;
856  constructor(n: string, a: number) {
857    this.name = n;
858    this.age = a;
859  }
860
861  getName(): string {
862    return this.name;
863  }
864}
865
866let p1 = new Person('Alice', 25);
867p1.name; // Alice
868let p2 = new Person('Bob', 28);
869p2.getName(); // Bob
870```
871
872**Static fields**
873
874The keyword `static` is used to declare a field as static. Static fields belong to the class itself, and all instances of the class share one static field.
875
876The class name is used to access a static field:
877
878```typescript
879class Person {
880  static numberOfPersons = 0;
881  constructor() {
882     // ...
883     Person.numberOfPersons++;
884     // ...
885  }
886}
887
888Person.numberOfPersons;
889```
890
891**Field initializers**
892
893ArkTS requires that all fields are explicitly initialized with some values either when the field is declared or in the `constructor`.
894This is similar to `strictPropertyInitialization` mode of the standard TypeScript. Such behavior is enforced to minimize the number of unexpected runtime errors and achieve better performance.
895
896The following code (invalid in ArkTS) is error-prone:
897
898```typescript
899class Person {
900  name: string; // undefined
901
902  setName(n:string): void {
903    this.name = n;
904  }
905
906  getName(): string {
907    // Return type "string" hides the fact that name can be undefined.
908    // The most correct action would be to write the return type as "string | undefined". By doing so, we could tell the users of our API about all possible return values.
909    return this.name;
910  }
911}
912
913let jack = new Person();
914// Assume that name is not assigned with a value, that is, jack.setName('Jack') is not called.
915jack.getName().length; // Runtime exception: name is undefined.
916```
917
918In ArkTS, you should write code as follows:
919
920```typescript
921class Person {
922  name: string = '';
923
924  setName(n:string): void {
925    this.name = n;
926  }
927
928  // The type is string in all cases, null and undefined are impossible.
929  getName(): string {
930    return this.name;
931  }
932}
933
934
935let jack = new Person();
936// Assume that name is not assigned with a value, that is, jack.setName('Jack') is not called.
937jack.getName().length; // 0, no runtime error.
938```
939
940The following shows how our code behaves if the field `name` can be `undefined`:
941
942```typescript
943class Person {
944  name?: string; // The field may be undefined.
945
946  setName(n:string): void {
947    this.name = n;
948  }
949
950  // Compilation error: name can be undefined. Therefore, the return value type of the API cannot be defined as string only.
951  getNameWrong(): string {
952    return this.name;
953  }
954
955  getName(): string | undefined { // Return type matches the type of name.
956    return this.name;
957  }
958}
959
960let jack = new Person();
961// Assume that name is not assigned with a value, that is, jack.setName('Jack') is not called.
962
963// Compile-time error: Compiler suspects that the next line of code possibly accesses something undefined.
964jack.getName().length;  // Compilation failed.
965
966jack.getName()?.length; // Successful compilation and no runtime error.
967```
968
969**getter and setter**
970
971**setter** and **getter** can be used to provide controlled access to object properties.
972
973In the following example, a **setter** is used to forbid setting invalid values of the `_age` property:
974
975```typescript
976class Person {
977  name: string = '';
978  private _age: number = 0;
979  get age(): number { return this._age; }
980  set age(x: number) {
981    if (x < 0) {
982      throw Error('Invalid age argument');
983    }
984    this._age = x;
985  }
986}
987
988let p = new Person();
989p.age; // Output 0.
990p.age = -42; // Error will be thrown as an attempt to set incorrect age.
991```
992
993A class can define a **getter** or a **setter**.
994
995### Method
996
997A method is a function that belongs to a class. A class can define instance methods, static methods or both. A static method belongs to the class itself, and can have access to static fields only. A `while` instance method has access to both static (class) fields and instance fields including private ones of its class.
998
999**Instance method**
1000
1001The example below illustrates how instance methods work.
1002
1003The `calculateArea` method calculates the area of a rectangle by multiplying the height by the width:
1004
1005```typescript
1006class RectangleSize {
1007  private height: number = 0;
1008  private width: number = 0;
1009  constructor(height: number, width: number) {
1010    this.height = height;
1011    this.width = width;
1012  }
1013  calculateArea(): number {
1014    return this.height * this.width;
1015  }
1016}
1017```
1018
1019To use an instance method, it must be called on an instance of the class:
1020
1021```typescript
1022let square = new RectangleSize(10, 10);
1023square.calculateArea(); // Output: 100
1024```
1025
1026**Static method**
1027
1028The keyword `static` is used to declare a method as static. A static method belongs to the class itself and have access to static fields only.
1029
1030A static method defines a common behavior of the class as a whole.
1031
1032The class name is used to call a static method.
1033
1034```typescript
1035class Cl {
1036  static staticMethod(): string {
1037    return 'this is a static method.';
1038  }
1039}
1040console.info(Cl.staticMethod());
1041```
1042
1043**Inheritance**
1044
1045A class can extend another class (called base class) and implement multiple APIs using the following syntax:
1046
1047```typescript
1048class [extends BaseClassName] [implements listOfInterfaces] {
1049  // ...
1050}
1051```
1052
1053An inheritance class extends the fields and methods of the base class, but does not extend the constructor. An inheritance class allows you to define new fields and methods or override the methods defined by the base class.
1054
1055The class that is being extended by another class is called 'base class', 'parent class', or 'superclass'. The class that extends another class is called 'extended class', 'derived class', or 'child class'.
1056
1057Example:
1058
1059```typescript
1060class Person {
1061  name: string = '';
1062  private _age = 0;
1063  get age(): number {
1064    return this._age;
1065  }
1066}
1067class Employee extends Person {
1068  salary: number = 0;
1069  calculateTaxes(): number {
1070    return this.salary * 0.42;
1071  }
1072}
1073```
1074
1075A class containing the `implements` clause must implement all methods defined in all listed APIs, except the methods defined with default implementation.
1076
1077```typescript
1078interface DateInterface {
1079  now(): string;
1080}
1081class MyDate implements DateInterface {
1082  now(): string {
1083    // Here is the implementation.
1084    return 'now';
1085  }
1086}
1087```
1088
1089**Access to super**
1090
1091The keyword `super` can be used to access instance fields, instance methods and constructors from the super class. It is often used to extend basic functionality of child class with the required behavior taken from the super class:
1092
1093```typescript
1094class RectangleSize {
1095  protected height: number = 0;
1096  protected width: number = 0;
1097
1098  constructor (h: number, w: number) {
1099    this.height = h;
1100    this.width = w;
1101  }
1102
1103  draw() {
1104    /* Draw bounds. */
1105  }
1106}
1107class FilledRectangle extends RectangleSize {
1108  color = ''
1109  constructor (h: number, w: number, c: string) {
1110    super(h, w); // Call of the super constructor.
1111    this.color = c;
1112  }
1113
1114  draw() {
1115    super.draw(); // Call of the super method.
1116    // super.height can be used here.
1117    /* Fill the rectangle. */
1118  }
1119}
1120```
1121
1122**Method overriding**
1123
1124A child class can override implementation of a method defined in its superclass. An overridden method must have the same types of parameters, and same or derived return type as the original method.
1125
1126```typescript
1127class RectangleSize {
1128  // ...
1129  area(): number {
1130    // Implementation
1131    return 0;
1132  }
1133}
1134class Square extends RectangleSize {
1135  private side: number = 0;
1136  area(): number {
1137    return this.side * this.side;
1138  }
1139}
1140```
1141
1142**Method overload signature**
1143
1144A method can be specified to be called in different ways by writing overload signatures. To do so, several methods' headers that have the same name but different signatures are written to the same method and immediately followed by the single implementation method.
1145
1146```typescript
1147class C {
1148  foo(x: number): void;            /* First signature */
1149  foo(x: string): void;            /* Second signature */
1150  foo(x: number | string): void {  /* Implementation signature */
1151  }
1152}
1153let c = new C();
1154c.foo(123);     // Use the first signature.
1155c.foo('aa'); // Use the second signature.
1156```
1157
1158An error occurs if two overload signatures have identical names and parameter lists.
1159
1160### Constructor
1161
1162A class declaration may contain a constructor that is used to initialize object state.
1163
1164A constructor is defined as follows:
1165
1166```typescript
1167constructor ([parameters]) {
1168  // ...
1169}
1170```
1171
1172If no constructor is defined, then a default constructor with an empty parameter list is created automatically. Example:
1173
1174```typescript
1175class Point {
1176  x: number = 0;
1177  y: number = 0;
1178}
1179let p = new Point();
1180```
1181
1182In this case, the default constructor fills the instance fields with default values for the field types.
1183
1184**Constructor in a derived class**
1185
1186The first statement of a constructor body can use the keyword `super` to explicitly call a constructor of the direct superclass.
1187
1188```typescript
1189class RectangleSize {
1190  constructor(width: number, height: number) {
1191    // ...
1192  }
1193}
1194class Square extends RectangleSize {
1195  constructor(side: number) {
1196    super(side, side);
1197  }
1198}
1199```
1200
1201**Constructor overload signature**
1202
1203A constructor can be specified to be called in different ways by writing overload signatures. To do so, several constructors' headers that have the same name but different signatures are written to the same constructor and immediately followed by the single implementation constructor.
1204
1205```typescript
1206class C {
1207  constructor(x: number)             /* First signature */
1208  constructor(x: string)             /* Second signature */
1209  constructor(x: number | string) {  /* Implementation signature */
1210  }
1211}
1212let c1 = new C(123);      // Use the first signature.
1213let c2 = new C('abc');    // Use the second signature.
1214```
1215
1216An error occurs if two overload signatures have identical names and parameter lists.
1217
1218### Visibility Modifiers
1219
1220Both methods and properties of a class can have visibility modifiers.
1221
1222Visibility modifiers include `private`, `protected`, and `public`. The default visibility is `public`.
1223
1224**Public**
1225
1226The `public` members (fields, methods, constructors) of a class are visible in any part of the program, where their class is visible.
1227
1228**Private**
1229
1230A `private` member cannot be accessed outside the class where it is declared in. Example:
1231
1232```typescript
1233class C {
1234  public x: string = '';
1235  private y: string = '';
1236  set_y (new_y: string) {
1237    this.y = new_y; // OK, as y is accessible within the class itself.
1238  }
1239}
1240let c = new C();
1241c.x = 'a'; // OK, as the field is public.
1242c.y = 'b'; // Compile-time error: 'y' is not visible.
1243```
1244
1245**Protected**
1246
1247The modifier `protected` acts much like the modifier `private`, but the `protected` members are also accessible in derived classes. Example:
1248
1249```typescript
1250class Base {
1251  protected x: string = '';
1252  private y: string = '';
1253}
1254class Derived extends Base {
1255  foo() {
1256    this.x = 'a'; // Access the protected member.
1257    this.y = 'b'; // Compile-time error: 'y' is not visible, because it is private.
1258  }
1259}
1260```
1261
1262### Object Literal
1263
1264An object literal is an expression that can be used to create a class instance and provide some initial values. It can be used instead of the expression `new` as it is more convenient in some cases.
1265
1266An object literal is a list of ***property name*: *value*** enclosed in a pair of curly brackets ({}).
1267
1268```typescript
1269class C {
1270  n: number = 0;
1271  s: string = '';
1272}
1273
1274let c: C = {n: 42, s: 'foo'};
1275```
1276
1277ArkTS is a statically typed language. As shown in the preceding example, object literals can be used only in contexts where the literal type can be inferred. Other valid cases are illustrated below:
1278
1279```typescript
1280class C {
1281  n: number = 0;
1282  s: string = '';
1283}
1284
1285function foo(c: C) {}
1286
1287let c: C
1288
1289c = {n: 42, s: 'foo'};  // Use the variable type.
1290foo({n: 42, s: 'foo'}); // Use the parameter type.
1291
1292function bar(): C {
1293  return {n: 42, s: 'foo'}; // Use the return type.
1294}
1295```
1296
1297You can also use the object literals in array element types or class field types.
1298
1299```typescript
1300class C {
1301  n: number = 0;
1302  s: string = '';
1303}
1304let cc: C[] = [{n: 1, s: 'a'}, {n: 2, s: 'b'}];
1305```
1306
1307**Object literal of `Record` type**
1308
1309The generic `Record<K, V>` type is used to map the properties of a type (Key type) to another type (Value type). A special form of object literal is used to initialize the value of such type:
1310
1311```typescript
1312let map: Record<string, number> = {
1313  'John': 25,
1314  'Mary': 21,
1315}
1316
1317map['John']; // 25
1318```
1319
1320The `K` type can be either string or number (excluding bigint), while `V` can be any type.
1321
1322```typescript
1323interface PersonInfo {
1324  age: number;
1325  salary: number;
1326}
1327let map: Record<string, PersonInfo> = {
1328  'John': { age: 25, salary: 10},
1329  'Mary': { age: 21, salary: 20}
1330}
1331```
1332
1333### Abstract Class
1334
1335A class with the modifier `abstract` is known as abstract class. Abstract classes can be used to represent notions that are common to some set of more concrete notions.
1336
1337A compile-time error occurs if an attempt is made to create an instance of an abstract class:
1338
1339```typescript
1340abstract class X {
1341  field: number;
1342  constructor(p: number) {
1343    this.field = p;
1344  }
1345}
1346
1347let x = new X(666)  // Compile-time error: Cannot create an instance of an abstract class.
1348```
1349
1350Child classes of an abstract class can be non-abstract or in turn abstract. A non-abstract child class of an abstract parent class can be instantiated. As a result, a constructor for the abstract class, and field initializers for non-static fields of that class are executed:
1351
1352```typescript
1353abstract class Base {
1354  field: number;
1355  constructor(p: number) {
1356    this.field = p;
1357  }
1358}
1359
1360class Derived extends Base {
1361  constructor(p: number) {
1362    super(p);
1363  }
1364}
1365
1366let x = new Derived(666);
1367```
1368
1369**Abstract method**
1370
1371A method with the modifier `abstract` is considered an abstract method. Abstract methods do not have bodies, that is, they can be declared but not implemented.
1372
1373Only abstract classes can have abstract methods. A compile-time error occurs if a non-abstract class has an abstract method:
1374
1375```typescript
1376class Y {
1377  abstract method(p: string) // Compile-time error: Abstract methods can only appear within an abstract class.
1378}
1379```
1380
1381## Interface
1382
1383An interface declaration introduces a new type. Interfaces are a common way of defining contracts between various part of codes.
1384
1385Interfaces are used to write polymorphic code, which can be applied to any class instances that implement a particular interface.
1386
1387An interface usually contains properties and method declarations.
1388
1389Example:
1390
1391```typescript
1392interface Style {
1393  color: string; // Property
1394}
1395interface AreaSize {
1396  calculateAreaSize(): number; // Method declaration
1397  someMethod(): void;     // Method declaration
1398}
1399```
1400
1401Example of a class implementing an interface:
1402
1403```typescript
1404// Interface:
1405interface AreaSize {
1406  calculateAreaSize(): number; // Method declaration
1407  someMethod(): void;     // Method declaration
1408}
1409
1410// Implementation
1411class RectangleSize implements AreaSize {
1412  private width: number = 0;
1413  private height: number = 0;
1414  someMethod(): void {
1415    console.info('someMethod called');
1416  }
1417  calculateAreaSize(): number {
1418    this.someMethod(); // Call another method and return the result.
1419    return this.width * this.height;
1420  }
1421}
1422```
1423
1424### Interface Property
1425
1426An interface property can be in a form of field, **getter**, **setter**, or both **getter** and **setter**.
1427
1428A property field is just a shortcut notation of a **getter** or **setter** pair, and the following notations are equal:
1429
1430```typescript
1431interface Style {
1432  color: string;
1433}
1434```
1435
1436```typescript
1437interface Style {
1438  get color(): string;
1439  set color(x: string);
1440}
1441```
1442
1443A class that implements an interface may also use a short or a long notation:
1444
1445```typescript
1446interface Style {
1447  color: string;
1448}
1449
1450class StyledRectangle implements Style {
1451  color: string = '';
1452}
1453```
1454
1455```typescript
1456interface Style {
1457  color: string;
1458}
1459
1460class StyledRectangle implements Style {
1461  private _color: string = '';
1462  get color(): string { return this._color; }
1463  set color(x: string) { this._color = x; }
1464}
1465```
1466
1467### Interface Inheritance
1468
1469An interface may extend other interfaces, as shown in the example below:
1470
1471```typescript
1472interface Style {
1473  color: string;
1474}
1475
1476interface ExtendedStyle extends Style {
1477  width: number;
1478}
1479```
1480
1481An extended interface contains all properties and methods of the interface it extends, and can also add its own properties and methods.
1482
1483
1484### Abstract Class and Interface
1485
1486Abstract classes and interfaces cannot be instantiated. Abstract classes are abstractions of classes, used to capture the general characteristics of child classes, and interfaces are abstractions of behavior. The differences between abstract classes and interfaces in ArkTS are as follows:
1487
1488* A class can extend only one abstract class, but can implement one or more interfaces.
1489```typescript
1490// The Bird class extends the abstract class Animal and implements multiple interfaces CanFly and CanSwim.
1491class Bird extends Animal implements CanFly, CanSwim {
1492  // ...
1493}
1494```
1495* An abstract class, instead of an interface, can contain static code blocks or static methods.
1496```typescript
1497interface MyInterface {
1498    // Error: The interface cannot contain static members.
1499    static staticMethod(): void;
1500
1501    // Error: The interface cannot contain static code blocks.
1502    static { console.info("static") };
1503}
1504
1505abstract class MyAbstractClass {
1506    // Correct: An abstract class can contain static methods.
1507    static staticMethod(): void { console.info("static");}
1508
1509    // Correct: An abstract class can contain static code blocks.
1510    static { console.info("static initialization block");}
1511}
1512```
1513* In abstract classes, there can be implementations of methods, but interfaces are completely abstract and there is no implementation of methods.
1514```typescript
1515abstract class MyAbstractClass {
1516   // Correct: An abstract class can contain implementation of methods.
1517   func(): void { console.info("func");}
1518}
1519interface MyInterface {
1520   // Error: Interfaces are completely abstract and there is no implementation of methods.
1521   func(): void { console.info("func");}
1522}
1523```
1524* Abstract classes can have constructors, while interfaces cannot.
1525```typescript
1526abstract class MyAbstractClass {
1527  constructor(){}  // Correct: Abstract classes can have constructors.
1528}
1529interface MyInterface {
1530  constructor(); // Error: Interfaces cannot contain constructors.
1531}
1532```
1533
1534## Generic Type and Function
1535
1536Generic type and function enable code to operate on multiple data types in a type-safe way without writing repetitive logic for each type.
1537
1538### Generic Class and Interface
1539
1540A class and an interface can be defined as generics. Add parameters to the type definition, such as the type parameter `Element` in the following example:
1541
1542```typescript
1543class CustomStack<Element> {
1544  public push(e: Element):void {
1545    // ...
1546  }
1547}
1548```
1549
1550To use type **CustomStack**, the type argument must be specified for each type parameter:
1551
1552```typescript
1553let s = new CustomStack<string>();
1554s.push('hello');
1555```
1556
1557Compiler ensures type safety while working with generic types and functions. Refer to the example below:
1558
1559```typescript
1560let s = new CustomStack<string>();
1561s.push(55); // A compile-time error is thrown.
1562```
1563
1564### Generic Constraints
1565
1566Type parameters of generic types can be bounded. For example, the `Key` type parameter in the `MyHashMap<Key, Value>` class must have the `hash` method.
1567
1568```typescript
1569interface Hashable {
1570  hash(): number;
1571}
1572class MyHashMap<Key extends Hashable, Value> {
1573  public set(k: Key, v: Value) {
1574    let h = k.hash();
1575    // Other code is omitted here.
1576  }
1577}
1578```
1579
1580In the above example, the `Key` type extends `Hashable`, and all methods of `Hashable` interface can be called for keys.
1581
1582### Generic Function
1583
1584Use a generic function to create a more universal code. Consider a function that returns the last element of the array:
1585
1586```typescript
1587function last(x: number[]): number {
1588  return x[x.length - 1];
1589}
1590last([1, 2, 3]); // 3
1591```
1592
1593If the same function needs to be defined for any array, then define it as a generic with a type parameter:
1594
1595```typescript
1596function last<T>(x: T[]): T {
1597  return x[x.length - 1];
1598}
1599```
1600
1601Now, the function can be used with any array.
1602
1603In a function call, type argument can be set explicitly or implicitly:
1604
1605```typescript
1606// Explicit type argument
1607let res: string = last<string>(['aa', 'bb']);
1608let res: number = last<number>([1, 2, 3]);
1609
1610// Implicit type argument
1611// Compiler determines the type argument based on the type of the call arguments.
1612let res: number = last([1, 2, 3]);
1613```
1614
1615### Generic Default
1616
1617Type parameters of generic types can have defaults. It allows using just the generic type name instead of specifying the actual type arguments. The example below illustrates this feature of both class and function.
1618
1619```typescript
1620class SomeType {}
1621interface Interface <T1 = SomeType> { }
1622class Base <T2 = SomeType> { }
1623class Derived1 extends Base implements Interface { }
1624// Derived1 is semantically equivalent to Derived2.
1625class Derived2 extends Base<SomeType> implements Interface<SomeType> { }
1626
1627function foo<T = number>(): T {
1628  // ...
1629}
1630foo();
1631// Such function is semantically equivalent to the call below:
1632foo<number>();
1633```
1634
1635## Null Safety
1636
1637All types in ArkTS by default are non-nullable, so the value of a type cannot be null. It is similar to TypeScript behavior in strict null checking mode (`strictNullChecks`), but the rules in ArkTS are stricter.
1638
1639In the following example, all lines lead to a compile-time error:
1640
1641```typescript
1642let x: number = null;    // Compile-time error
1643let y: string = null;    // Compile-time error
1644let z: number[] = null;  // Compile-time error
1645```
1646
1647A variable that can have a null value is defined with a union type `T | null`.
1648
1649```typescript
1650let x: number | null = null;
1651x = 1;    // ok
1652x = null; // ok
1653if (x != null) { /* do something */ }
1654```
1655
1656### Non-Null Assertion Operator
1657
1658A postfix operator `!` can be used to assert that its operand is non-null.
1659
1660When applied to a value of a nullable type, the type becomes non-nullable at compile time. For example, the type of the value is changed from `T | null` to `T`:
1661
1662```typescript
1663class A {
1664  value: number = 0;
1665}
1666
1667function foo(a: A | null) {
1668  a.value;   // Compile-time error: cannot access to a nullable value.
1669  a!.value;  // If the value of a is not null at runtime, the fields of a can be accessed; if the value of a is null at runtime, a runtime exception occurs.
1670}
1671```
1672
1673### Null-Coalescing Operator
1674
1675The null-coalescing binary operator `??` checks whether the evaluation of the left-hand-side expression is equal to `null` or `undefined`. If it is, the result of the expression is the right-hand-side expression; otherwise, it is the left-hand-side expression.
1676
1677In other words, `a ?? b` equals the ternary operator `(a != null && a != undefined) ? a : b`.
1678
1679In the following example, the `getNick` method returns a nickname if it is set; otherwise, an empty string is returned:
1680
1681```typescript
1682class Person {
1683  // ...
1684  nick: string | null = null;
1685  getNick(): string {
1686    return this.nick ?? '';
1687  }
1688}
1689```
1690
1691### Optional Chaining
1692
1693If the object property is `undefined` or `null` when it is being accessed, the optional chaining operator returns `undefined`.
1694
1695```typescript
1696class Person {
1697  nick: string | null = null;
1698  spouse?: Person
1699
1700  setSpouse(spouse: Person): void {
1701    this.spouse = spouse;
1702  }
1703
1704  getSpouseNick(): string | null | undefined {
1705    return this.spouse?.nick;
1706  }
1707
1708  constructor(nick: string) {
1709    this.nick = nick;
1710    this.spouse = undefined;
1711  }
1712}
1713```
1714
1715Note: The return type of `getSpouseNick` must be `string | null | undefined`, as the method can return `null` or `undefined`.
1716
1717The optional chaining can be of any length and can contain any number of `?.` operators.
1718
1719In the following example, if the `spouse` property of the `Person` instance and the `nick` property of `spouse` both are not null, the `spouse.nick` is output. Otherwise, `undefined` is output.
1720
1721```typescript
1722class Person {
1723  nick: string | null = null;
1724  spouse?: Person;
1725
1726  constructor(nick: string) {
1727    this.nick = nick;
1728    this.spouse = undefined;
1729  }
1730}
1731
1732let p: Person = new Person('Alice');
1733p.spouse?.nick; // undefined
1734```
1735
1736## Module
1737
1738Programs are organized as sets of compilation units or modules.
1739
1740Each module creates its own scope, that is, any declarations (variables, functions, classes, etc.) declared in the module are not visible outside that module unless they are explicitly exported.
1741
1742Conversely, a variable, function, class, or interface exported from another module must first be imported to a module.
1743
1744### Export
1745
1746A top-level declaration can be exported by using the keyword `export`.
1747
1748A declared name that is not exported is considered private and can be used only in the module where it is declared.
1749
1750```typescript
1751export class Point {
1752  x: number = 0;
1753  y: number = 0;
1754  constructor(x: number, y: number) {
1755    this.x = x;
1756    this.y = y;
1757  }
1758}
1759export let Origin = new Point(0, 0);
1760export function Distance(p1: Point, p2: Point): number {
1761  return Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
1762}
1763```
1764**Exporting default objects**
1765```typescript
1766class Demo{
1767  constructor(){
1768  }
1769}
1770export default new Demo();
1771
1772```
1773
1774### Import
1775
1776**Static import**
1777
1778Import declarations are used to import entities exported from other modules and provide their bindings in the current module. An import declaration consists of two parts:
1779
1780* Import path that determines the module to import from.
1781* Import bindings that define the set of usable entities in the imported module, and the form of use (qualified or unqualified).
1782
1783Import bindings may have several forms.
1784
1785Let's assume a module has the path **./utils** and export entities **X** and **Y**.
1786
1787An import binding of the form `* as A` binds the name 'A', and all entities exported from the module defined by the import path can be accessed by using the qualified name `A.name`:
1788
1789```typescript
1790import * as Utils from './utils';
1791Utils.X // Denote X from Utils.
1792Utils.Y // Denote Y from Utils.
1793```
1794
1795An import binding of the form `{ ident1, ..., identN }` binds an exported entity with a specified name, which can be used as a simple name:
1796
1797```typescript
1798import { X, Y } from './utils';
1799X // Denote X from utils.
1800Y // Denote Y from utils.
1801```
1802
1803If a list of identifiers contains an alias in the form `ident as alias`, the entity `ident` is bound under the name `alias`:
1804
1805```typescript
1806import { X as Z, Y } from './utils';
1807Z // Denote X from Utils.
1808Y // Denote Y from Utils.
1809X // Compile-time error: 'X' is not visible.
1810```
1811
1812**Dynamic import**
1813Unlike static import, dynamic import allows you to load a module conditionally or on demand.
1814The **import()** syntax, commonly called dynamic import, is a function-like expression that allows for dynamic loading of a module. A promise is returned when this method is invoked.
1815In the following example, **import(modulePath)** loads a module and returns a promise that resolves into a module object that contains all its exports. This expression can be called from any place in the code.
1816
1817```typescript
1818// Calc.ts
1819export function add(a:number, b:number):number {
1820  let c = a + b;
1821  console.info('Dynamic import, %d + %d = %d', a, b, c);
1822  return c;
1823}
1824
1825// Index.ts
1826import("./Calc").then((obj: ESObject) => {
1827  console.info(obj.add(3, 5));
1828}).catch((err: Error) => {
1829  console.error("Module dynamic import error: ", err);
1830});
1831```
1832
1833You can also use **let module = await import(modulePath)** inside an async function.
1834
1835```typescript
1836// say.ts
1837export function hi() {
1838  console.info('Hello');
1839}
1840export function bye() {
1841  console.info('Bye');
1842}
1843```
1844
1845Then dynamic import can be like this:
1846
1847```typescript
1848async function test() {
1849  let ns = await import('./say');
1850  let hi = ns.hi;
1851  let bye = ns.bye;
1852  hi();
1853  bye();
1854}
1855```
1856
1857For more details about dynamic import, see [Dynamic Import](../arkts-utils/arkts-dynamic-import.md).
1858
1859<!--RP2--><!--RP2End-->
1860
1861### Top-Level Statement
1862
1863Top-level statements are those written at the outermost layer of a module, not wrapped by any function, class, or block scope. These statements include variable declarations, function declarations, and expressions.
1864
1865## Keyword
1866
1867### this
1868
1869The keyword `this` can only be used in instance methods of a class.
1870
1871**Example**
1872
1873```typescript
1874class A {
1875  count: string = 'a';
1876  m(i: string): void {
1877    this.count = i;
1878  }
1879}
1880```
1881
1882Constraints:
1883
1884* Type notation using `this` is not supported.
1885* `this` is not allowed in functions and static methods of classes.
1886
1887**Example**
1888
1889```typescript
1890class A {
1891  n: number = 0;
1892  f1(arg1: this) {} // Compile-time error: Type notation using this is not supported.
1893  static f2(arg1: number) {
1894    this.n = arg1;  // Compile-time error: `this` is not allowed in the static methods of classes.
1895  }
1896}
1897
1898function foo(arg1: number) {
1899  this.n = i;       // Compile-time error: `this` is not allowed in functions.
1900}
1901```
1902
1903The keyword `this` used as a primary expression denotes a value that is a reference to the following:
1904
1905* Object for which the instance method
1906* Object being constructed
1907
1908## Annotation
1909
1910Annotation is a language feature that changes the semantics of application declarations by adding metadata.
1911The declaration and usage of annotations are as follows:
1912
1913**Example**
1914
1915```typescript
1916// Declaration of an annotation:
1917@interface ClassAuthor {
1918  authorName: string
1919}
1920
1921// Usage of an annotation:
1922@ClassAuthor({authorName: "Bob"})
1923class MyClass {
1924  // ...
1925}
1926```
1927
1928- The `ClassAuthor` annotation should add metadata to the class declaration.
1929- The annotation must be placed before the declaration.
1930- The annotation can contain the parameters shown in the preceding example.
1931
1932The name of the annotation to be used must be prefixed with the `@` symbol (for example, **@MyAnno**). No space or line separator is allowed between the `@` symbol and the name.
1933```typescript
1934ClassAuthor({authorName: "Bob"}) // Compile-time error: The annotation must be prefixed with '@'.
1935@ ClassAuthor({authorName: "Bob"}) // Compile-time error: No space or line separator is allowed between the @ symbol and the name.
1936```
1937If the annotation name cannot be accessed, a compile-time error occurs.
1938Annotation declarations can be exported and used in other files.
1939
1940Multiple annotations can be applied to the same declaration (the sequence of annotations does not affect the usage).
1941```typescript
1942@MyAnno()
1943@ClassAuthor({authorName: "John Smith"})
1944class MyClass {
1945  // ...
1946}
1947```
1948Annotations are not features in TypeScript and can be used only in `.ets` and `.d.ets` files.
1949
1950### Custom Annotation
1951
1952**Declaration of custom annotation**
1953The definition of custom annotation is similar to that of `interface`. The `interface` keyword is prefixed with the `@` symbol.<br>
1954The following types can be used for annotation fields:
1955* Number
1956* Boolean
1957* String
1958* Enum
1959* Array of the preceding types
1960>**NOTE**
1961>
1962> - If other types are used for annotation fields, a compile-time error occurs.
1963> - The bigint type is not supported for annotation field.
1964
1965The default value of an annotation field must be specified using a constant expression.<br>The following types of constant expressions are used:
1966* Numeric literal
1967* Boolean literal
1968* String literal
1969* Enum (values must be determined during compilation)
1970* Array of the preceding constants
1971>**NOTE**
1972>
1973> If the enums cannot be determined during compilation, a compile-time error is reported.
1974```typescript
1975// a.ts
1976export enum X {
1977  x = foo(); // x is not a constant that can be determined during compilation.
1978}
1979
1980// b.ets
1981import {X} from './a';
1982
1983@interface Position {
1984  data: number = X.x; // Compile-time error: The default value of the annotation field must be a constant expression.
1985}
1986```
1987Annotations must be defined in the top-level scope. Otherwise, a compile-time error is reported.<br>
1988The name of an annotation cannot be the same as that of another entity visible in the scope where the annotation is defined. Otherwise, a compile-time error is reported.<br>
1989Annotations do not support the merging feature in TypeScript. Otherwise, a compile-time error is reported.
1990```typescript
1991namespace ns {
1992  @interface MataInfo { // Compile-time error: Annotations must be defined in the top-level scope.
1993    // ...
1994  }
1995}
1996
1997@interface Position {
1998  // ...
1999}
2000
2001class Position { // Compile-time error: The name of an annotation cannot be the same as that of another entity visible in the scope where the annotation is defined.
2002  // ...
2003}
2004
2005@interface ClassAuthor {
2006  name: string;
2007}
2008
2009@interface ClassAuthor { // Compile-time error: The name of an annotation cannot be the same as that of another entity visible in the scope where the annotation is defined.
2010  data: sting;
2011}
2012```
2013Annotations are not types. If annotations are used as types, a compile-time error is reported. For example, type aliases are used for annotations.
2014```typescript
2015@interface Position {}
2016type Pos = Position; // Compile-time error: Annotations are not types.
2017```
2018Annotations cannot be added to the **getter** and **setter** methods of a class. Otherwise, a compile-time error is reported.
2019```typescript
2020@interface ClassAuthor {
2021  authorName: string;
2022}
2023
2024@ClassAuthor({authorName: "John Smith"})
2025class MyClass {
2026  private _name: string = "Bob";
2027
2028  @ClassAuthor({authorName: "John Smith"}) // Compile-time error: Annotations cannot be added to the getter and setter methods of a class.
2029  get name() {
2030    return this._name;
2031  }
2032
2033  @ClassAuthor({authorName: "John Smith"}) // Compile-time error: Annotations cannot be added to the getter and setter methods of a class.
2034  set name(authorName: string) {
2035    this._name = authorName;
2036  }
2037}
2038```
2039
2040**Usage of custom annotation**
2041The following is an example of annotation declaration:
2042```typescript
2043@interface ClassPreamble {
2044  authorName: string;
2045  revision: number = 1;
2046}
2047@interface MyAnno {}
2048```
2049Currently, annotations can be used only for class declarations and method declarations. The same annotation can be used for classes and methods.<br>The following is an example of annotation usage:
2050```typescript
2051@ClassPreamble({authorName: "John", revision: 2})
2052class C1 {
2053  // ...
2054}
2055
2056@ClassPreamble({authorName: "Bob"}) // The default value of revision is 1.
2057class C2 {
2058  // ...
2059}
2060
2061@MyAnno() // The same annotation can be used for classes and methods.
2062class C3 {
2063  @MyAnno()
2064  foo() {}
2065  @MyAnno()
2066  static bar() {}
2067}
2068```
2069The field sequence in an annotation does not affect the usage.
2070```typescript
2071@ClassPreamble({authorName: "John", revision: 2})
2072// the same as:
2073@ClassPreamble({revision: 2, authorName: "John"})
2074```
2075When using an annotation, you must assign values to the fields that do not have default values. Otherwise, a compile-time error occurs.
2076>**NOTE**
2077>
2078> The value to assign must be of the same type as the annotation declaration and only constant expressions can be used.
2079```typescript
2080@ClassPreamble() // Compile-time error: The authorName field is not defined.
2081class C1 {
2082  // ...
2083}
2084```
2085If a field of the array type is defined in an annotation, use an array literal to set the value of the field.
2086```typescript
2087@interface ClassPreamble {
2088  authorName: string;
2089  revision: number = 1;
2090  reviewers: string[];
2091}
2092
2093@ClassPreamble(
2094  {
2095    authorName: "Alice",
2096    reviewers: ["Bob", "Clara"]
2097  }
2098)
2099class C3 {
2100  // ...
2101}
2102```
2103If it is not necessary to define an annotation field, you can omit the parentheses following the annotation name.
2104```typescript
2105@MyAnno
2106class C4 {
2107  // ...
2108}
2109```
2110
2111**Importing and exporting annotations**
2112Annotations can also be imported and exported. Currently, only the annotations in the `export @interface` form can be exported.<br>
2113**Example**
2114```typescript
2115export @interface MyAnno {}
2116```
2117Currently, only the annotations in the `import {}` and `import * as` forms can be imported.<br>
2118**Example**
2119```typescript
2120// a.ets
2121export @interface MyAnno {}
2122export @interface ClassAuthor {}
2123
2124// b.ets
2125import { MyAnno } from './a';
2126import * as ns from './a';
2127
2128@MyAnno
2129@ns.ClassAuthor
2130class C {
2131  // ...
2132}
2133```
2134- Annotation renaming is not allowed in **import**.
2135```typescript
2136import { MyAnno as Anno } from './a'; // Compile-time error: Annotation renaming is not allowed in import.
2137```
2138Any other forms of **import** or **export** are not allowed for annotations. Otherwise, a compile-time error is reported.
2139- As annotations are not types, the `type` symbol is not allowed for import and export.
2140```typescript
2141import type { MyAnno } from './a'; // Compile-time error: The type symbol is not allowed for annotation import and export.
2142```
2143
2144- If an annotation is imported only from a module, the module side effects will not be triggered.
2145```typescript
2146// a.ets
2147export @interface Anno {}
2148
2149export @interface ClassAuthor {}
2150
2151console.info("hello");
2152
2153// b.ets
2154import { Anno } from './a';
2155import * as ns from './a';
2156
2157@MyAnno
2158@ns.ClassAuthor // Only the annotation of ns is referenced, which does not execute console.info of a.ets.
2159class X {
2160  // ...
2161}
2162```
2163
2164**Annotations in .d.ets files**
2165Annotations can be used in .d.ets files.
2166You can declare annotations using ambient declarations in .d.ets files.
2167```typescript
2168ambientAnnotationDeclaration:
2169  'declare' userDefinedAnnotationDeclaration
2170  ;
2171```
2172
2173**Example**
2174```typescript
2175// a.d.ets
2176export declare @interface ClassAuthor {}
2177```
2178In the preceding declaration:
2179- No new annotation definition is introduced, but the annotation type information is provided.
2180- Annotations must be defined in other source code files.
2181- The ambient declaration and implementation of an annotation must be the same, including the field type and default value.
2182```typescript
2183// a.d.ets
2184export declare @interface NameAnno{name: string = ""}
2185
2186// a.ets
2187export @interface NameAnno{name: string = ""} // ok
2188```
2189The ambient declaration of an annotation is similar to that of a class and can also be imported.
2190```typescript
2191// a.d.ets
2192export declare @interface MyAnno {}
2193
2194// b.ets
2195import { MyAnno } from './a';
2196
2197@MyAnno
2198class C {
2199  // ...
2200}
2201```
2202
2203**.d.ets files automatically generated by a compiler**<br>
2204When a compiler automatically generates .d.ets files based on ETS code, the following situations may occur:
22051. When the annotation definition is exported, the annotation definition in the source code is retained in the .d.ets file.
2206```typescript
2207// a.ets
2208export @interface ClassAuthor {}
2209
2210@interface MethodAnno { // Not exported
2211  data: number;
2212}
2213
2214// Declaration file generated by the a.d.ets compiler
2215export declare @interface ClassAuthor {}
2216```
22172. If all the following conditions are met, the annotation instance of the entity in the source code is retained in the .d.ets file.<br>
2218    2.1 The annotation definition (including imported annotation) is exported.<br>
2219    2.2 If the entity is a class, the class is exported.<br>
2220    2.3 If the entity is a method, the class is exported, and the method is not private.
2221```typescript
2222// a.ets
2223import { ClassAuthor } from './author';
2224
2225export @interface MethodAnno {
2226  data: number = 0;
2227}
2228
2229@ClassAuthor
2230class MyClass {
2231  @MethodAnno({data: 123})
2232  foo() {}
2233
2234  @MethodAnno({data: 456})
2235  private bar() {}
2236}
2237
2238// Declaration file generated by the a.d.ets compiler
2239import {ClassAuthor} from "./author";
2240
2241export declare @interface MethodAnno {
2242  data: number = 0;
2243}
2244
2245@ClassAuthor
2246export declare class C {
2247  @MethodAnno({data: 123})
2248  foo(): void;
2249
2250  bar; // Annotations are not retained for private methods.
2251}
2252```
2253
2254**.d.ets file generated by the developer**<br>
2255The annotation information in the .d.ets file generated by you is not automatically applied to the implemented source code.<br>
2256**Example**
2257```typescript
2258// Declaration file generated by you in b.d.ets
2259@interface ClassAuthor {}
2260
2261@ClassAuthor // The declaration file contains annotations.
2262class C {
2263  // ...
2264}
2265
2266// Source code of the declaration file implemented by you in b.ets
2267@interface ClassAuthor {}
2268
2269// The implementation file does not contain annotations.
2270class C {
2271  // ...
2272}
2273```
2274In the final build product, **class C** does not have annotations.
2275
2276**Duplicate annotations and inheritance**
2277The same annotation cannot be used repeatedly for the same entity. Otherwise, a compile-time error occurs.
2278```typescript
2279@MyAnno({name: "123", value: 456})
2280@MyAnno({name: "321", value: 654}) // Compile-time error: Duplicate annotations are not allowed.
2281class C {
2282  // ...
2283}
2284```
2285A child class does not extend the annotations of the base class or that of the methods of the base class.
2286
2287**Annotations, abstract classes, and abstract methods**
2288Annotations cannot be used for abstract classes or abstract methods. Otherwise, a compile-time error occurs.
2289```typescript
2290@MyAnno // Compile-time error: Annotations cannot be used for abstract classes and abstract methods.
2291abstract class C {
2292  @MyAnno
2293  abstract foo(): void; // Compile-time error: Annotations cannot be used for abstract classes and abstract methods.
2294}
2295```
2296
2297## ArkUI Supports
2298
2299This section demonstrates the mechanism provided by ArkTS for creating GUIs. ArkUI provides a series of extended capabilities based on TypeScript to declaratively describe the GUIs of an application and the interaction between GUI components.
2300
2301
2302### ArkUI Example
2303
2304[MVVM code example](../ui/state-management/arkts-mvvm.md#example) provides a complete ArkUI-based application to demonstrate its GUI programming features.
2305
2306For more details about ArkUI features, see [Basic Syntax Overview](../ui/state-management/arkts-basic-syntax-overview.md).
2307