1# Introduction to ArkTS
2
3Welcome to the tutorial for ArkTS, a TypeScript-based programming language designed specifically to build high-performance mobile applications!
4
5ArkTS is optimized to provide better performance and efficiency, while still maintaining the familiar syntax of TypeScript.
6
7As mobile devices continue to become more prevalent in our daily lives, there is a growing need for programming languages optimized for the mobile environment. Many current programming languages were not designed with mobile devices in mind, resulting in slow and inefficient applications that drain battery life. ArkTS has been specifically designed to address such concerns by prioritizing higher execution efficiency.
8
9ArkTS 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.
10
11One of the key features of ArkTS is its focus on low runtime overhead.
12ArkTS 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.
13
14Interoperability with JavaScript was a critical consideration in the ArkTS language design. Many mobile app 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.
15
16To ensure best experience for UI app development for OpenHarmony ecosystem, ArkTS provides support for ArkUI, including its declarative syntax and other features. Since this feature is outside the scope of the "stock" TypeScript, a verbose ArkUI example is provided in a separate chapter.
17
18This 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. For details about programming specifications, see [ArkTS Coding Style Guide](../../contribute/OpenHarmony-ArkTS-coding-style-guide.md).<!--RP1--><!--RP1End-->
19
20For a more detailed understanding of the ArkTS language, please refer to the [ArkTS Specific Guide](https://gitee.com/openharmony/docs/blob/master/en/application-dev/arkts-utils/arkts-overview.md).
21
22## The Basics
23
24### Declarations
25
26Declarations in ArkTS introduce:
27
28- Variables
29- Constants
30- Functions
31- Types
32
33#### Variable Declaration
34
35A declaration starting with the keyword `let` introduces a variable which can have different values during program execution.
36
37```typescript
38let hi: string = 'hello';
39hi = 'hello, world';
40```
41
42#### Constant Declaration
43
44A declaration starting with the keyword `const` introduces a read-only constant that can be assigned only once.
45
46```typescript
47const hello: string = 'hello';
48```
49
50A compile-time error occurs if a new value is assigned to a constant.
51
52#### Automatic Type Inference
53
54As ArkTS is a statically typed language, the types of all entities, like variables and constants, have to be known at compile time.
55
56However, developers do not need to explicitly specify the type of a declared entity if a variable or a constant declaration contains an initial value.
57
58All cases that allow the type to be inferred automatically are specified in the ArkTS Specification.
59
60Both variable declarations are valid, and both variables are of the `string` type:
61
62```typescript
63let hi1: string = 'hello';
64let hi2 = 'hello, world';
65```
66
67### Types
68
69#### Numeric Types
70
71ArkTS has `number` and `Number` numeric types. Any integer and floating-point values can be assigned to a variable of these types.
72
73Numeric literals include integer literals and floating-point literals
74with the decimal base.
75
76Integer literals include the following:
77
78* Decimal integers that consist of a sequence of digits. For example: `0`, `117`, `-345`.
79* Hexadecimal integers that start with 0x (or 0X), and can contain digits (0-9) and letters a-f or A-F. For example: `0x1123`, `0x00111`, `-0xF1A7`.
80* Octal integers that start with 0o (or 0O) and can only contain digits (0-7). For example: `0o777`.
81* Binary integers that start with 0b (or 0B), and can only contain the digits 0 and 1. For example: `0b11`, `0b0011`, `-0b11`.
82
83A floating-point literal includes the following:
84
85* Decimal integer, optionally signed (i.e., prefixed with "+" or "-");
86* Decimal point (".").
87* Fractional part (represented by a string of decimal digits).
88* Exponent part that starts with "e" or "E", followed by an optionally signed (i.e., prefixed with "+" or "-") integer.
89
90Example:
91
92```typescript
93let n1 = 3.14;
94let n2 = 3.141592;
95let n3 = .5;
96let n4 = 1e2;
97
98function factorial(n: number): number {
99  if (n <= 1) {
100    return 1;
101  }
102  return n * factorial(n - 1);
103}
104
105factorial(n1)  //  7.660344000000002
106factorial(n2)  //  7.680640444893748
107factorial(n3)  //  1
108factorial(n4)  //  9.33262154439441e+157
109```
110
111#### `Boolean`
112
113The `boolean` type represents logical values that are either `true` or `false`.
114
115Usually variables of this type are used in conditional statements:
116
117```typescript
118let isDone: boolean = false;
119
120// ...
121
122if (isDone) {
123  console.log ('Done!');
124}
125```
126
127#### `String`
128
129A `string` is a sequence of characters; some characters can be set by using escape sequences.
130
131A `string` literal consists of zero or more characters enclosed in single (') or double quotes ("). The special form of string literals are template literals enclosed in backtick quotes (\`).
132
133```typescript
134let s1 = 'Hello, world!\n';
135let s2 = 'this is a string';
136let a = 'Success';
137let s3 = `The result is ${a}`;
138```
139
140#### `Void` Type
141
142The `void` type is used to specify that a function does not return a value.
143This type has the only one value which is also `void`. As `void` is
144a reference type, it can be used as type argument for generic types.
145
146```typescript
147class Class<T> {
148  //...
149}
150let instance: Class <void>
151```
152
153#### `Object` Type
154
155An `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.
156
157#### `Array` Type
158
159An `array` is an object comprised of elements of data types assignable to the element type specified in the array declaration.
160A value of an `array` is set by using *array composite literal*, that 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.
161
162The following example creates the `array` with three elements:
163
164```typescript
165let names: string[] = ['Alice', 'Bob', 'Carol'];
166```
167
168#### `Enum` Type
169
170An `enum` type is a value type with a defined set of named values called enum constants.
171In order to be used, an `enum` constant must be prefixed with an enum `type` name.
172
173```typescript
174enum ColorSet { Red, Green, Blue }
175let c: ColorSet = ColorSet.Red;
176```
177
178A constant expression can be used to explicitly set the value of an `enum` constant.
179
180```typescript
181enum ColorSet { White = 0xFF, Grey = 0x7F, Black = 0x00 }
182let c: ColorSet = ColorSet.Black
183```
184
185#### `Union` Type
186
187A `union` type is a reference type which is created as a combination of other types. Values of union types can be valid values of all types a union was created from.
188
189```typescript
190class Cat {
191  name: string = 'cat';
192  // ...
193}
194class Dog {
195  name: string = 'dog';
196  // ...
197}
198class Frog {
199  name: string = 'frog';
200  // ...
201}
202type Animal = Cat | Dog | Frog | number
203// Cat, Dog, and Frog are some types (class or interface ones)
204
205let animal: Animal = new Cat();
206animal = new Frog();
207animal = 42;
208// One may assign the variable of the union type with any valid value
209```
210
211There are different mechanisms to get a value of a particular type from a union.
212
213Example:
214
215```typescript
216class Cat { sleep () {}; meow () {} }
217class Dog { sleep () {}; bark () {} }
218class Frog { sleep () {}; leap () {} }
219
220type Animal = Cat | Dog | Frog;
221
222function foo(animal: Animal) {
223  if (animal instanceof Frog) {
224    animal.leap();  // animal is of type Frog here
225  }
226  animal.sleep(); // Any animal can sleep
227}
228```
229
230#### Type `Aliases`
231
232Type `aliases` provides names for anonymous types (array, function, object literal or union types) or alternative names for existing types.
233
234```typescript
235type Matrix = number[][];
236type Handler = (s: string, no: number) => string;
237type Predicate <T> = (x: T) => boolean;
238type NullableObject = Object | null;
239```
240
241### Operators
242
243#### Assignment Operators
244
245Simple assignment operator '=' is used as in "x = y".
246
247Compound assignment operators combine an assignment with an operator, where `x op = y` equals `x = x op y`.
248
249Compound assignment operators are as follows: `+=`, `-=`, `*=`, `/=`, `%=`, `<<=`, `>>=`, `>>>=`, `&=`, `|=`, `^=`.
250
251#### Comparison Operators
252
253| Operator | Description                                                  |
254| -------- | ------------------------------------------------------------ |
255| `===`    | Returns true if both operands are strict equal.              |
256| `!==`    | Returns true if both operands are nots trict equal.          |
257| `==`     | Returns true if both operands are equal.                     |
258| `!=`     | Returns true if both operands are not equal.                 |
259| `>`      | Returns true if the left operand is greater than the right.  |
260| `>=`     | Returns true if the left operand is greater than or equal to the right. |
261| `<`      | Returns true if the left operand is less than the right.     |
262| `<=`     | Returns true if the left operand is less than or equal to the right. |
263#### Arithmetic Operators
264
265Unary operators are `-`, `+`, `--` and `++`.
266
267Binary operators are as follows:
268
269| Operator   | Description              |
270|------------|--------------------------|
271| `+`        | addition                 |
272| `-`        | subtraction              |
273| `*`        | multiplication           |
274| `/`        | division                 |
275| `%`        | remainder after division |
276#### Bitwise Operators
277
278| Operator   | Description                                                                                                     |
279|------------|-----------------------------------------------------------------------------------------------------------------|
280| `a & b`    | Bitwise AND: sets each bit to 1 if the corresponding bits of both operands are 1, otherwise to 0.               |
281| `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. |
282| `a ^ b`    | Bitwise XOR: sets each bit to 1 if the corresponding bits of both operands are different, otherwise to 0.       |
283| `~ a`      | Bitwise NOT: inverts the bits of the operand.                                                                   |
284| `a << b`   | Shift left: shifts the binary representation of *a* to the left by *b* bits.                                    |
285| `a >> b`   | Arithmetic right shift: shifts the binary representation of *a* to the right by *b* bits with sign-extension.   |
286| `a >>> b`  | Logical right shift: shifts the binary representation of *a* to the right by *b* bits with zero-extension.      |
287#### Logical Operators
288
289| Operator   | Description   |
290|------------|---------------|
291| `a && b`   | Logical AND  |
292| `a \|\| b`   | Logical OR   |
293| `! a`      | Logical NOT  |
294### Statements
295
296#### `If` Statements
297
298An `if` statement is used to execute a sequence of statements when a logical condition is `true`, or another set of statements (if provided) otherwise.
299
300The `else` part can also contain more `if` statements.
301
302An `if` statement looks as follows:
303
304```typescript
305if (condition1) {
306  // statements1
307} else if (condition2) {
308  // statements2
309} else {
310  // else_statements
311}
312```
313
314All conditional expressions must be of the type `boolean` or other types (`string`, `number`, etc.). For types other than `boolean`, implicit conversion rules apply:
315
316```typescript
317let s1 = 'Hello';
318if (s1) {
319  console.log(s1); // prints 'Hello'
320}
321
322let s2 = 'World';
323if (s2.length != 0) {
324  console.log(s2); // prints 'World'
325}
326```
327
328#### `Switch` Statements
329
330A `switch` statement is used to execute a sequence of statements that match the value of a switch expression.
331
332A `switch` statement looks as follows:
333
334```typescript
335switch (expression) {
336  case label1: // will be executed if label1 is matched
337    // ...
338    // statements1
339    // ...
340    break; // Can be omitted
341  case label2:
342  case label3: // will be executed if label2 or label3 is matched
343    // ...
344    // statements23
345    // ...
346    break; // Can be omitted
347  default:
348    // default_statements
349}
350```
351
352If the value of a `switch` expression equals the value of some label, then the corresponding statements are executed.
353
354If there is no match, and the `switch` has the default clause, then the default statements are executed.
355
356An optional `break` statement allows you to break out of the `switch` and continue executing the statement that follows the `switch`.
357
358If there is no `break`, then the next statements in the `switch` are executed.
359
360#### Conditional Expressions
361
362The conditional expression `? :` uses the `boolean` value of the first expression to decide which of two other expressions to evaluate.
363
364A conditional expression looks as follows:
365
366```typescript
367condition ? expression1 : expression2
368```
369
370If that logical expression is truthy(a value that is considered `true`), then the first expression is used as the result of the ternary expression; otherwise, the second expression is used.
371
372Example:
373
374```typescript
375let isValid = Math.random() > 0.5 ? true : false;
376let message = isValid ? 'Valid' : 'Failed';
377```
378
379#### `For` Statements
380
381A `for` statement is executed repeatedly until the specified loop exit condition is `false`.
382
383A `for` statement looks as follows:
384
385```typescript
386for ([init]; [condition]; [update]) {
387  statements
388}
389```
390
391When a `for` statement is executed, the following process takes place:
392
3931. An `init` expression is executed, if any. This expression usually initializes one or more loop counters.
3942. The condition is evaluated. If the value of condition is truthy(a value that is considered `true`), or if the conditional expression is omitted, then the statements in the `for` body are to be executed. If the value of condition is falsy(a value that is considered `false`), then the `for` loop terminates.
3953. The statements of the `for` body are executed.
3964. If there is an `update` expression, then the `update` expression is executed.
3975. Go back to step 2.
398
399Example:
400
401```typescript
402let sum = 0;
403for (let i = 0; i < 10; i += 2) {
404  sum += i;
405}
406```
407
408#### `For-of` Statements
409
410`for-of` statements are used to iterate over an array or string.
411
412A `for-of` statement looks as follows:
413
414```typescript
415for (forVar of expression) {
416  statements
417}
418```
419
420Example:
421
422```typescript
423for (let ch of 'a string object') {
424  /* process ch */
425}
426```
427
428#### `While` Statements
429
430A `while` statement has its body statements executed as long as the specified condition evaluates to `true`.
431
432A `while` statement looks as follows:
433
434```typescript
435while (condition) {
436  statements
437}
438```
439
440Example:
441
442```typescript
443let n = 0;
444let x = 0;
445while (n < 3) {
446  n++;
447  x += n;
448}
449```
450
451#### `Do-while` Statements
452
453`do-while` statements are executed repetitively until a specified condition evaluates to `false`.
454
455A `do-while` statement looks as follows:
456
457```typescript
458do {
459  statements
460} while (condition)
461```
462
463Example:
464
465```typescript
466let i = 0;
467do {
468  i += 1;
469} while (i < 10)
470```
471
472#### `Break` Statements
473
474A `break` statement is used to terminate any `loop` statement or `switch`.
475
476Example:
477
478```typescript
479let x = 0;
480while (true) {
481  x++;
482  if (x > 5) {
483    break;
484  }
485}
486```
487
488A `break` statement with a label identifier transfers control out of the enclosing statement to the one which has the same label identifier.
489
490Example:
491
492```typescript
493let x = 1;
494label: while (true) {
495  switch (x) {
496    case 1:
497      // statements
498      break label; // breaks the while
499  }
500}
501```
502
503#### `Continue` Statements
504
505A `continue` statement stops the execution of the current loop iteration and passes control to the next iteration.
506
507Example:
508
509```typescript
510let sum = 0;
511for (let x = 0; x < 100; x++) {
512  if (x % 2 == 0) {
513    continue;
514  }
515  sum += x;
516}
517```
518
519#### `Throw` and `Try` Statements
520
521A `throw` statement is used to throw an exception or an error:
522
523```typescript
524throw new Error('this error')
525```
526
527A `try` statement is used to catch and handle an exception or an error:
528
529```typescript
530try {
531  // try block
532} catch (e) {
533  // handle the situation
534}
535```
536
537The example below shows the `throw` and `try` statements  used to handle the zero division case:
538
539```typescript
540class ZeroDivisor extends Error {}
541
542function divide (a: number, b: number): number{
543  if (b == 0) throw new ZeroDivisor();
544  return a / b;
545}
546
547function process (a: number, b: number) {
548  try {
549    let res = divide(a, b);
550    console.log('result: ' + res);
551  } catch (x) {
552    console.log('some error');
553  }
554}
555```
556
557`finally` clause is also supported:
558
559```typescript
560function processData(s: string) {
561  let error: Error | null = null;
562
563  try {
564    console.log('Data processed: ' + s);
565    // ...
566    // Throwing operations
567    // ...
568  } catch (e) {
569    error = e as Error;
570    // ...
571    // More error handling
572    // ...
573  } finally {
574    if (error != null) {
575      console.log(`Error caught: input='${s}', message='${error.message}'`);
576    }
577  }
578}
579```
580
581## Functions
582
583### Function Declarations
584
585A function declaration introduces a named function, specifying its name, parameters, return type and body.
586
587Below is a simple function with two string parameters and string return type:
588
589```typescript
590function add(x: string, y: string): string {
591  let z: string = `${x} ${y}`;
592  return z;
593}
594```
595
596For every parameter its type annotation must be specified.
597An optional parameter allows you to omit the corresponding argument when calling a function. The last parameter of a function can be a rest parameter.
598
599### Optional Parameters
600
601An optional parameter has the form `name?: Type`.
602
603```typescript
604function hello(name?: string) {
605  if (name == undefined) {
606    console.log('Hello!');
607  } else {
608    console.log(`Hello, ${name}!`);
609  }
610}
611```
612
613Another form contains an expression that specifies a default value.
614If the corresponding argument to such parameter is omitted in a function call, then this parameter's value is default.
615
616```typescript
617function multiply(n: number, coeff: number = 2): number {
618  return n * coeff;
619}
620multiply(2);  // returns 2*2
621multiply(2, 3); // returns 2*3
622```
623
624### The Rest Parameter
625
626The last parameter of a function can be a rest parameter. It allows functions or methods to take unlimited number of arguments.
627
628```typescript
629function sum(...numbers: number[]): number {
630  let res = 0;
631  for (let n of numbers)
632    res += n;
633  return res;
634}
635
636sum(); // returns 0
637sum(1, 2, 3); // returns 6
638```
639
640### Return Types
641
642If function return type can be inferred from its body content, then it can be omitted from the function declaration.
643
644```typescript
645// Explicit return type
646function foo(): string { return 'foo'; }
647
648// Implicit return type inferred as string
649function goo() { return 'goo'; }
650```
651
652The 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.
653
654Both notations below are valid:
655
656```typescript
657function hi1() { console.log('hi'); }
658function hi2(): void { console.log('hi'); }
659```
660
661### Function Scope
662
663Variables and other entities defined in a function are local to the function and cannot be accessed from the outside.
664
665If 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.
666
667### Function Calls
668
669Calling a function actually leads to the execution of its body, while the arguments of the call are assigned to the function parameters.
670
671If the function is defined as follows:
672
673```typescript
674function join(x: string, y: string): string {
675  let z: string = `${x} ${y}`;
676  return z;
677}
678```
679
680then it is called with two arguments of the type `string`:
681
682```typescript
683let x = join('hello', 'world');
684console.log(x);
685```
686
687## Function Types
688
689Function types are commonly used as follows to define callbacks:
690
691```typescript
692type trigFunc = (x: number) => number // this is a function type
693
694function do_action(f: trigFunc) {
695   f(3.141592653589); // call the function
696}
697
698do_action(Math.sin); // pass the function as the parameter
699```
700
701### Arrow Functions (Lambdas Functions)
702
703A function can be defined as an arrow function, for example:
704
705```typescript
706let sum = (x: number, y: number): number => {
707  return x + y;
708}
709```
710
711An arrow function return type can be omitted; in such case, it is inferred from the function body.
712
713An expression can be specified as an arrow function to make the notation shorter, i.e., the following two notations are equivalent:
714
715```typescript
716let sum1 = (x: number, y: number) => { return x + y; }
717let sum2 = (x: number, y: number) => x + y
718```
719
720### Closure
721
722A 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.
723
724In the following example, **z** is a reference to the instance of the function **g** that is created when **f** is executed. The instance of **g** maintains a reference to its lexical environment, within which the variable **count** exists. For this reason, when **z** is invoked, the variable **count** remains available for use.
725
726```typescript
727function f(): () => number {
728  let count = 0;
729  let g = (): number => { count++; return count; };
730  return g;
731}
732
733let z = f();
734z(); // output: 1
735z(); // output: 2
736```
737
738### Function Overload Signatures
739
740A 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 and immediately followed by the single implementation function.
741
742```typescript
743function foo(x: number): void;            /* 1st signature */
744function foo(x: string): void;            /* 2nd signature */
745function foo(x: number | string): void {  /* Implementation signature */
746}
747
748foo(123);   // ok, 1st signature is used
749foo('aa');  // ok, 2nd signature is used
750```
751
752An error occurs if two overload signatures have identical parameter lists.
753
754## Classes
755
756A class declaration introduces a new type and defines its fields, methods and constructors.
757
758In the following example, class `Person` is defined, which has fields **name** and **surname**, constructor, and a method `fullName`:
759
760```typescript
761class Person {
762  name: string = '';
763  surname: string = '';
764  constructor (n: string, sn: string) {
765    this.name = n;
766    this.surname = sn;
767  }
768  fullName(): string {
769    return this.name + ' ' + this.surname;
770  }
771}
772```
773
774After the class is defined, its instances can be created by using the keyword `new`:
775
776```typescript
777let p = new Person('John', 'Smith');
778console.log(p.fullName());
779```
780
781or an instance can be created by using object literals:
782
783```typescript
784class Point {
785  x: number = 0;
786  y: number = 0;
787}
788let p: Point = {x: 42, y: 42};
789```
790
791### Fields
792
793A field is a variable of some type that is declared directly in a class.
794
795Classes may have instance fields, static fields or both.
796
797#### Instance Fields
798
799Instance fields exist on every instance of a class. Each instance has its own set of instance fields.
800
801An instance of the class is used to access an instance field.
802
803```typescript
804class Person {
805  name: string = '';
806  age: number = 0;
807  constructor(n: string, a: number) {
808    this.name = n;
809    this.age = a;
810  }
811
812  getName(): string {
813    return this.name;
814  }
815}
816
817let p1 = new Person('Alice', 25);
818p1.name;
819let p2 = new Person('Bob', 28);
820p2.getName();
821```
822
823#### Static Fields
824
825The 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.
826
827The class name is used to access a static field:
828
829```typescript
830class Person {
831  static numberOfPersons = 0;
832  constructor() {
833     // ...
834     Person.numberOfPersons++;
835     // ...
836  }
837}
838
839Person.numberOfPersons;
840```
841
842#### Field Initializers
843
844ArkTS requires that all fields are explicitly initialized with some values either when the field is declared or in the `constructor`. This 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.
845
846The following code (invalid in ArkTS) is error-prone:
847
848```typescript
849class Person {
850  name: string; // undefined
851
852  setName(n:string): void {
853    this.name = n;
854  }
855
856  getName(): string {
857    // Return type "string" hides from the developers the fact
858    // that name can be undefined. The most correct would be
859    // to write the return type as "string | undefined". By doing so
860    // we tell the users of our API about all possible return values.
861    return this.name;
862  }
863}
864
865let jack = new Person();
866// Let's assume that the developer forgets to call setName:
867// jack.setName('Jack')
868jack.getName().length; // runtime exception: name is undefined
869```
870
871Here is how it should look in ArkTS:
872
873```typescript
874class Person {
875  name: string = '';
876
877  setName(n:string): void {
878    this.name = n;
879  }
880
881  // The type is always string, no other "hidden options".
882  getName(): string {
883    return this.name;
884  }
885}
886
887
888let jack = new Person();
889// Let's assume that the developer forgets to call setName:
890// jack.setName('Jack')
891jack.getName().length; // 0, no runtime error
892```
893
894And here how our code behaves if the field `name` can be `undefined`
895
896```typescript
897class Person {
898  name?: string; // The field may be undefined
899
900  setName(n:string): void {
901    this.name = n;
902  }
903
904  // Compile-time error:
905  // name can be "undefined", so we cannot say to those who use this API
906  // that it returns only strings:
907  getNameWrong(): string {
908    return this.name;
909  }
910
911  getName(): string | undefined { // Return type matches the type of name
912    return this.name;
913  }
914}
915
916let jack = new Person()
917// Let's assume that the developer forgets to call setName:
918// jack.setName('Jack')
919
920// Compile-time(!) error: Compiler suspects that we
921// may possibly access something undefined and won't build the code:
922jack.getName().length; // The code won't build and run
923
924jack.getName()?.length; // Builds ok, no runtime error
925```
926
927#### Getters and Setters
928
929Setters and getters can be used to provide controlled access to object properties.
930
931In the following example, a setter is used to forbid setting invalid values of the '_age' property:
932
933```typescript
934class Person {
935  name: string = '';
936  private _age: number = 0;
937  get age(): number { return this._age; }
938  set age(x: number) {
939    if (x < 0) {
940      throw Error('Invalid age argument');
941    }
942    this._age = x;
943  }
944}
945
946let p = new Person();
947p.age; // 0
948p.age = -42; // Error will be thrown as an attempt to set incorrect age
949```
950
951A class can define a getter, a setter or both.
952
953### Methods
954
955A method is a function that belongs to a class.
956A class can define instance methods, static methods or both.
957A static method belongs to the class itself, and can have access to static fields only.
958A `while` instance method has access to both static (class) fields and instance fields including private ones of its class.
959
960### Instance Methods
961
962The example below illustrates how instanced methods work.
963The `calculateArea` method calculates the area of a rectangle by multiplying the height by the width:
964
965```typescript
966class RectangleSize {
967  private height: number = 0;
968  private width: number = 0;
969  constructor(height: number, width: number) {
970    this.height = height;
971    this.width = width;
972  }
973  calculateArea(): number {
974    return this.height * this.width;
975  }
976}
977```
978
979To use an instance method, it must be called on an instance of the class:
980
981```typescript
982let square = new RectangleSize(10, 10);
983square.calculateArea(); // output: 100
984```
985
986#### Static Methods
987
988The keyword `static` is used to declare a method as static. Static methods belong to the class itself and have access to static fields only.
989A static method defines a common behavior of the class as a whole.
990
991The class name is used to call a static method:
992
993```typescript
994class Cl {
995  static staticMethod(): string {
996    return 'this is a static method.';
997  }
998}
999console.log(Cl.staticMethod());
1000```
1001
1002#### Inheritance
1003
1004A class can extend another class.
1005The class that is being extended by another class is called ‘*base class*’, ‘parent class’, or ‘superclass’.
1006The class that extends another class is called ‘*extended class*’, ‘derived class’, or ‘subclass’.
1007
1008An extended class can implement several interfaces by using the following syntax:
1009
1010```typescript
1011class [extends BaseClassName] [implements listOfInterfaces] {
1012  // ...
1013}
1014```
1015
1016An extended class inherits fields and methods, but not constructors from the base class, and can add its own fields and methods, as well as override methods defined by the base class.
1017
1018Example:
1019
1020```typescript
1021class Person {
1022  name: string = '';
1023  private _age = 0;
1024  get age(): number {
1025    return this._age;
1026  }
1027}
1028class Employee extends Person {
1029  salary: number = 0;
1030  calculateTaxes(): number {
1031    return this.salary * 0.42;
1032  }
1033}
1034```
1035
1036A class containing the `implements` clause must implement all methods defined in all listed interfaces, except the methods defined with default implementation.
1037
1038```typescript
1039interface DateInterface {
1040  now(): string;
1041}
1042class MyDate implements DateInterface {
1043  now(): string {
1044    // implementation is here
1045    return 'now';
1046  }
1047}
1048```
1049
1050#### Access to Super
1051
1052The keyword `super` can be used to access instance fields, instance methods and constructors from the super class.
1053
1054It is often used to extend basic functionality of subclass with the required behavior taken from the super class:
1055
1056```typescript
1057class RectangleSize {
1058  protected height: number = 0;
1059  protected width: number = 0;
1060
1061  constructor (h: number, w: number) {
1062    this.height = h;
1063    this.width = w;
1064  }
1065
1066  draw() {
1067    /* draw bounds */
1068  }
1069}
1070class FilledRectangle extends RectangleSize {
1071  color = ''
1072  constructor (h: number, w: number, c: string) {
1073    super(h, w); // call of super constructor
1074    this.color = c;
1075  }
1076
1077  draw() {
1078    super.draw(); // call of super methods
1079    // super.height - can be used here
1080    /* fill rectangle */
1081  }
1082}
1083```
1084
1085#### Override Methods
1086
1087A subclass can override implementation of a method defined in its superclass.
1088An overridden method must have the same types of parameters, and same or derived return type as the original method.
1089
1090```typescript
1091class RectangleSize {
1092  // ...
1093  area(): number {
1094    // implementation
1095    return 0;
1096  }
1097}
1098class Square extends RectangleSize {
1099  private side: number = 0;
1100  area(): number {
1101    return this.side * this.side;
1102  }
1103}
1104```
1105
1106#### Method Overload Signatures
1107
1108A method can be specified to be called in different ways by writing overload signatures. To do so, several method headers that have the same name but different signatures are written and immediately followed by the single implementation method.
1109
1110```typescript
1111class C {
1112  foo(x: number): void;            /* 1st signature */
1113  foo(x: string): void;            /* 2nd signature */
1114  foo(x: number | string): void {  /* implementation signature */
1115  }
1116}
1117let c = new C();
1118c.foo(123);   // ok, 1st signature is used
1119c.foo('aa');  // ok, 2nd signature is used
1120```
1121
1122An error occurs if two overload signatures have the same name and identical parameter lists.
1123
1124### Constructors
1125
1126A class declaration may contain a constructor that is used to initialize object state.
1127
1128A constructor is defined as follows:
1129
1130```typescript
1131constructor ([parameters]) {
1132  // ...
1133}
1134```
1135
1136If no constructor is defined, then a default constructor with an empty parameter list is created automatically, for example:
1137
1138```typescript
1139class Point {
1140  x: number = 0;
1141  y: number = 0;
1142}
1143let p = new Point();
1144```
1145
1146In this case the default constructor fills the instance fields with default values for the field types.
1147
1148#### Constructors in Derived Class
1149
1150The first statement of a constructor body can use the keyword `super` to explicitly call a constructor of the direct superclass.
1151
1152```typescript
1153class RectangleSize {
1154  constructor(width: number, height: number) {
1155    // ...
1156  }
1157}
1158class Square extends RectangleSize {
1159  constructor(side: number) {
1160    super(side, side);
1161  }
1162}
1163```
1164
1165#### Constructor Overload Signatures
1166
1167A constructor can be specified to be called in different ways by writing overload signatures. To do so, several constructor headers that have the same name but different signatures are written and immediately followed by the single implementation constructor.
1168
1169```typescript
1170class C {
1171  constructor(x: number)             /* 1st signature */
1172  constructor(x: string)             /* 2nd signature */
1173  constructor(x: number | string) {  /* Implementation signature */
1174  }
1175}
1176let c1 = new C(123);    // ok, 1st signature is used
1177let c2 = new C('abc');  // ok, 2nd signature is used
1178```
1179
1180An error occurs if two overload signatures have the same name and identical parameter lists.
1181
1182### Visibility Modifiers
1183
1184Both methods and properties of a class can have visibility modifiers.
1185
1186There are several visibility modifiers:
1187
1188- `private`
1189- `protected`
1190- `public`
1191
1192The default visibility is `public`.
1193
1194#### Public Visibility
1195
1196The `public` members (fields, methods, constructors) of a class are visible in any part of the program, where their class is visible.
1197
1198### Private Visibility
1199
1200A `private` member cannot be accessed outside the class it is declared in.
1201Example:
1202
1203```typescript
1204class C {
1205  public x: string = '';
1206  private y: string = '';
1207  set_y (new_y: string) {
1208    this.y = new_y // ok, as y is accessible within the class itself
1209  }
1210}
1211let c = new C();
1212c.x = 'a'; // ok, the field is public
1213c.y = 'b'; // compile-time error: 'y' is not visible
1214```
1215
1216#### Protected Visibility
1217
1218The modifier `protected` acts much like the modifier `private`, but the `protected` members are also accessible in derived classes.
1219Example:
1220
1221```typescript
1222class Base {
1223  protected x: string = '';
1224  private y: string = '';
1225}
1226class Derived extends Base {
1227  foo() {
1228    this.x = 'a'; // ok, access to protected member
1229    this.y = 'b'; // compile-time error, 'y' is not visible, as it is private
1230  }
1231}
1232```
1233
1234### Object Literals
1235
1236An 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.
1237
1238A class composite is written as a comma-separated list of name-value pairs enclosed in '{' and '}'.
1239
1240```typescript
1241class C {
1242  n: number = 0;
1243  s: string = '';
1244}
1245
1246let c: C = {n: 42, s: 'foo'};
1247```
1248
1249Due to the static typing of the ArkTS, object literals can be used in a context where the class or interface type of the object literal can be inferred as in the example above. Other valid cases are illustrated below:
1250
1251```typescript
1252class C {
1253  n: number = 0;
1254  s: string = '';
1255}
1256
1257function foo(c: C) {}
1258
1259let c: C;
1260
1261c = {n: 42, s: 'foo'};  // type of the variable is used
1262foo({n: 42, s: 'foo'}); // type of the parameter is used
1263
1264function bar(): C {
1265  return {n: 42, s: 'foo'}; // return type is used
1266}
1267```
1268
1269The type of an array element or of a class field can also be used:
1270
1271```typescript
1272class C {
1273  n: number = 0;
1274  s: string = '';
1275}
1276let cc: C[] = [{n: 1, s: 'a'}, {n: 2, s: 'b'}];
1277```
1278
1279#### Object Literals of Record Type
1280
1281The generic Record<K, V> type is used to map the properties of a type (Key type) to another type (Value type).
1282
1283A special form of object literal is used to initialize the value of such type:
1284
1285```typescript
1286let map: Record<string, number> = {
1287  'John': 25,
1288  'Mary': 21,
1289}
1290
1291map['John']; // 25
1292```
1293
1294The K type can be either string or number, while V can be any type.
1295
1296```typescript
1297interface PersonInfo {
1298  age: number;
1299  salary: number;
1300}
1301let map: Record<string, PersonInfo> = {
1302  'John': { age: 25, salary: 10},
1303  'Mary': { age: 21, salary: 20}
1304}
1305```
1306
1307### Abstract Classes
1308
1309A 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.
1310
1311A compile-time error occurs if an attempt is made to create an instance of an abstract class:
1312
1313```typescript
1314abstract class X {
1315  field: number;
1316  constructor(p: number) {
1317    this.field = p;
1318  }
1319}
1320
1321let x = new X(666)  // Compile-time error: Cannot create an instance of an abstract class.
1322```
1323
1324Subclasses of an abstract class can be non-abstract or in turn abstract. A non-abstract subclass of an abstract superclass can be instantiated. As a result, a constructor for the abstract class, and field initializers for non-static fields of that class are executed:
1325
1326```typescript
1327abstract class Base {
1328  field: number;
1329  constructor(p: number) {
1330    this.field = p;
1331  }
1332}
1333
1334class Derived extends Base {
1335  constructor(p: number) {
1336    super(p);
1337  }
1338}
1339```
1340
1341#### Abstract Methods
1342
1343A method with the modifier abstract is considered an abstract method. Abstract methods do not have bodies, i.e., they can be declared but not implemented.
1344
1345Only abstract classes can have abstract methods. A compile-time error occurs if a non-abstract class has an abstract method:
1346
1347```typescript
1348class Y {
1349  abstract method(p: string)  //Compile-time error: Abstract methods can only appear within an abstract class.
1350}
1351```
1352
1353## Interfaces
1354
1355An interface declaration introduces a new type. Interfaces are a common way of defining contracts between various part of codes.
1356
1357Interfaces are used to write polymorphic code, which can be applied to any class instances that implement a particular interface.
1358
1359An interface usually contains properties and method headers.
1360
1361Examples:
1362
1363```typescript
1364interface Style {
1365  color: string; // property
1366}
1367interface AreaSize {
1368  calculateAreaSize(): number; // method header
1369  someMethod(): void;    // method header
1370}
1371```
1372
1373Examples of a class implementing an interface:
1374
1375```typescript
1376// Interface:
1377interface AreaSize {
1378  calculateAreaSize(): number; // method header
1379  someMethod(): void;    // method header
1380}
1381
1382// Implementation:
1383class RectangleSize implements AreaSize {
1384  private width: number = 0;
1385  private height: number = 0;
1386  someMethod(): void {
1387    console.log('someMethod called');
1388  }
1389  calculateAreaSize(): number {
1390    this.someMethod(); // calls another method and returns result
1391    return this.width * this.height;
1392  }
1393}
1394```
1395
1396### Interface Properties
1397
1398An interface property can be in a form of field, getter, setter, or both getter and setter.
1399
1400A property field is just a shortcut notation of a getter/setter pair, and the following notations are equal:
1401
1402```typescript
1403interface Style {
1404  color: string;
1405}
1406```
1407
1408```typescript
1409interface Style {
1410  get color(): string
1411  set color(x: string)
1412}
1413```
1414
1415A class that implements an interface may also use a short or a long notation:
1416
1417```typescript
1418interface Style {
1419  color: string;
1420}
1421
1422class StyledRectangle implements Style {
1423  color: string = '';
1424}
1425```
1426
1427```typescript
1428interface Style {
1429  color: string;
1430}
1431
1432class StyledRectangle implements Style {
1433  private _color: string = '';
1434  get color(): string { return this._color; }
1435  set color(x: string) { this._color = x; }
1436}
1437```
1438
1439### Interface Inheritance
1440
1441An interface may extend other interfaces like in the example below:
1442
1443```typescript
1444interface Style {
1445  color: string;
1446}
1447
1448interface ExtendedStyle extends Style {
1449  width: number;
1450}
1451```
1452
1453An extended interface contains all properties and methods of the interface it extends, and can also add its own properties and methods.
1454
1455
1456### Abstract class and interface
1457
1458Abstract classes and interfaces cannot be instantiated. Abstract classes are abstractions of classes, used to capture the general characteristics of subclasses, and interfaces are abstractions of behavior. The difference between abstract classes and interfaces in ArkTS is as follows:
1459
1460* Abstract classes can only inherit from a single source, while interfaces can be implemented in multiple layers;
1461* In abstract classes, there can be implementations of methods, but interfaces are completely abstract and there is no implementation of methods;
1462* The interface cannot contain static code blocks and static methods, while abstract classes can have static code blocks and static functions;
1463* Abstract classes can have constructors, while interfaces cannot have constructors.
1464
1465## Generic Types and Functions
1466
1467Generic types and functions allow creating the code capable to work over a variety of types rather than a single type.
1468
1469### Generic Classes and Interfaces
1470
1471A class and an interface can be defined as generics, adding parameters to the type definition, like the type parameter `Element` in the following example:
1472
1473```typescript
1474class CustomStack<Element> {
1475  public push(e: Element):void {
1476    // ...
1477  }
1478}
1479```
1480
1481To use type CustomStack, the type argument must be specified for each type parameter:
1482
1483```typescript
1484let s = new CustomStack<string>();
1485s.push('hello');
1486```
1487
1488Compiler ensures type safety while working with generic types and functions.
1489See below:
1490
1491```typescript
1492let s = new CustomStack<string>();
1493s.push(55); // That will be a compile-time error as 55 is not compatible with type string.
1494```
1495
1496### Generic Constraints
1497
1498Type parameters of generic types can be bounded. For example, the `Key` type parameter in the `MyHashMap<Key, Value>` container must have the `hash` method.
1499
1500```typescript
1501interface Hashable {
1502  hash(): number;
1503}
1504class MyHashMap<Key extends Hashable, Value> {
1505  public set(k: Key, v: Value) {
1506    let h = k.hash();
1507    // ... other code ...
1508  }
1509}
1510```
1511
1512In the above example, the `Key` type extends `Hashable`, and all methods of `Hashable` interface can be called for keys.
1513
1514### Generic Functions
1515
1516Use a generic function to create a more universal code. Consider a function that returns the last element of the array:
1517
1518```typescript
1519function last(x: number[]): number {
1520  return x[x.length - 1];
1521}
1522last([1, 2, 3]); // output: 3
1523```
1524
1525If the same function needs to be defined for any array, then define it as a generic with a type parameter:
1526
1527```typescript
1528function last<T>(x: T[]): T {
1529  return x[x.length - 1];
1530}
1531```
1532
1533Now, the function can be used with any array.
1534
1535In a function call, type argument can be set explicitly or implicitly:
1536
1537```typescript
1538// Explicit type argument
1539last<string>(['aa', 'bb']);
1540last<number>([1, 2, 3]);
1541
1542// Implicit type argument:
1543// Compiler understands the type argument based on the type of the call arguments
1544last([1, 2, 3]);
1545```
1546
1547### Generic Defaults
1548
1549Type parameters of generic types can have defaults. It allows using just the generic type name instead of specifying the actual type arguments.
1550The example below illustrates this for both classes and functions.
1551
1552```typescript
1553class SomeType {}
1554interface Interface <T1 = SomeType> { }
1555class Base <T2 = SomeType> { }
1556class Derived1 extends Base implements Interface { }
1557// Derived1 is semantically equivalent to Derived2
1558class Derived2 extends Base<SomeType> implements Interface<SomeType> { }
1559
1560function foo<T = number>(): T {
1561  // ...
1562}
1563foo();
1564// such function is semantically equivalent to the call below
1565foo<number>();
1566```
1567
1568## Null Safety
1569
1570All types in ArkTS by default are non-nullable, so the value of a type cannot be null.
1571It is similar to TypeScript behavior in strict null checking mode (`strictNullChecks`), but the rules are stricter.
1572
1573In the example below, all lines cause a compile-time error:
1574
1575```typescript
1576let x: number = null;    // Compile-time error
1577let y: string = null;    // Compile-time error
1578let z: number[] = null;  // Compile-time error
1579```
1580
1581A variable that can have a null value is defined with a union type `T | null`.
1582
1583```typescript
1584let x: number | null = null;
1585x = 1;    // ok
1586x = null; // ok
1587if (x != null) { /* do something */ }
1588```
1589
1590### Non-Null Assertion Operator
1591
1592A postfix operator `!` can be used to assert that its operand is non-null.
1593
1594If applied to a null value, the operator throws an error. Otherwise, the type of the value is changed from `T | null` to `T`:
1595
1596```typescript
1597class A {
1598  value: number = 0;
1599}
1600
1601function foo(a: A | null) {
1602  a.value;   // compile time error: cannot access to a nullable value
1603
1604  // ok, if the value of a is not null at runtime, the fields of a can be accessed;
1605  // If the value of runtime a is empty, a runtime exception occurs.
1606  a!.value;
1607}
1608```
1609
1610### Null-Coalescing Operator
1611
1612The null-coalescing binary operator `??` checks whether the evaluation of the left-hand-side expression is equal to `null` or `undefined`.
1613If it is, then the result of the expression is the right-hand-side expression; otherwise, it is the left-hand-side expression.
1614
1615In other words, `a ?? b` equals the ternary operator `(a != null && a != undefined) ? a : b`.
1616
1617In the following example, the method `getNick` returns a nickname if it is set; otherwise, an empty string is returned:
1618
1619```typescript
1620class Person {
1621  // ...
1622  nick: string | null = null;
1623  getNick(): string {
1624    return this.nick ?? '';
1625  }
1626}
1627```
1628
1629### Optional Chaining
1630
1631Optional chaining operator `?.` allows writing code where the evaluation stops at an expression that is partially evaluated to `null` or `undefined`.
1632
1633```typescript
1634class Person {
1635  nick: string | null = null;
1636  spouse?: Person;
1637
1638  setSpouse(spouse: Person): void {
1639    this.spouse = spouse;
1640  }
1641
1642  getSpouseNick(): string | null | undefined {
1643    return this.spouse?.nick;
1644  }
1645
1646  constructor(nick: string) {
1647    this.nick = nick;
1648    this.spouse = undefined;
1649  }
1650}
1651```
1652
1653**Note**: The return type of `getSpouseNick` must be `string | null | undefined`, as the method can return `null` or `undefined`.
1654
1655An optional chain can be of any length and contain any number of `?.` operators.
1656
1657In the following sample, the output is a person's spouse nickname if that person has a spouse, and the spouse has a nickname.
1658
1659Otherwise, the output is `undefined`:
1660
1661```typescript
1662class Person {
1663  nick: string | null = null;
1664  spouse?: Person;
1665
1666  constructor(nick: string) {
1667    this.nick = nick;
1668    this.spouse = undefined;
1669  }
1670}
1671
1672let p: Person = new Person('Alice');
1673p.spouse?.nick; // undefined
1674```
1675
1676## Modules
1677
1678Programs are organized as sets of compilation units or modules.
1679
1680Each module creates its own scope, i.e., any declarations (variables, functions, classes, etc.) declared in the module are not visible outside that module unless they are explicitly exported.
1681
1682Conversely, a variable, function, class, interface, etc. exported from another module must first be imported to a module.
1683
1684### Export
1685
1686A top-level declaration can be exported by using the keyword `export`.
1687
1688A declared name that is not exported is considered private and can be used only in the module where it is declared.
1689
1690**NOTE**: Use braces ({}) when importing a declaration that was exported using the keyword `export`.
1691
1692```typescript
1693export class Point {
1694  x: number = 0;
1695  y: number = 0;
1696  constructor(x: number, y: number) {
1697    this.x = x;
1698    this.y = y;
1699  }
1700}
1701export let Origin = new Point(0, 0);
1702export function Distance(p1: Point, p2: Point): number {
1703  return Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
1704}
1705```
1706
1707### Import
1708
1709#### Static Import
1710
1711Import declarations are used to import entities exported from other modules and provide their bindings in the current module.
1712An import declaration consists of two parts:
1713
1714* Import path that determines the module to import from.
1715* Import bindings that define the set of usable entities in the imported module, and the form of use (i.e., qualified or unqualified use).
1716
1717Import bindings may have several forms.
1718
1719Let's assume a module has the path './utils' and export entities 'X' and 'Y'.
1720
1721An 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`:
1722
1723```typescript
1724import * as Utils from './utils'
1725Utils.X // denotes X from Utils
1726Utils.Y // denotes Y from Utils
1727```
1728
1729An import binding of the form `{ ident1, ..., identN }` binds an exported entity with a specified name, which can be used as a simple name:
1730
1731```typescript
1732import { X, Y } from './utils'
1733X // denotes X from Utils
1734Y // denotes Y from Utils
1735```
1736
1737If a list of identifiers contains aliasing of the form `ident as alias`, then entity `ident` is bound under the name `alias`:
1738
1739```typescript
1740import { X as Z, Y } from './utils'
1741Z // denotes X from Utils
1742Y // denotes Y from Utils
1743X // Compile-time error: 'X' is not visible
1744```
1745#### Dynamic Import
1746Unlike static import, static import allows you to load a module conditionally or on demand.
1747The **import() **syntax, commonly called dynamic import, is a function-like expression that allows for dynamic loading of a module. It returns a promise.
1748In the following example, **import(modulePath)** loads the 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.
1749
1750```typescript
1751let modulePath = prompt("Which module to load?");
1752import(modulePath)
1753.then(obj => <module object>)
1754.catch(err => <loading error, e.g. if no such module>)
1755```
1756
1757You can also use **let module = await import(modulePath)** inside an async function.
1758
1759```typescript
1760// say.ts
1761export function hi() {
1762  console.log('Hello');
1763}
1764export function bye() {
1765  console.log('Bye');
1766}
1767```
1768
1769Then dynamic import can be like this:
1770
1771```typescript
1772async function test() {
1773  let ns = await import('./say');
1774  let hi = ns.hi;
1775  let bye = ns.bye;
1776  hi();
1777  bye();
1778}
1779```
1780
1781For more details about dynamic import, see [Dynamic Import](arkts-dynamic-import.md).
1782
1783<!--RP2--><!--RP2End-->
1784
1785### Top-Level Statements
1786
1787A module can contain any statements at the module level, except `return` ones.
1788
1789## Keywords
1790
1791### this
1792
1793The keyword `this` can only be used in instance methods of a class.
1794
1795**Example**
1796
1797```typescript
1798class A {
1799  count: string = 'a';
1800  m(i: string): void {
1801    this.count = i;
1802  }
1803}
1804```
1805
1806Constraints:
1807
1808* Type notation using `this` is not supported.
1809* Using `this` inside standalone functions is not supported.
1810
1811**Example**
1812
1813```typescript
1814class A {
1815  n: number = 0;
1816  f1(arg1: this) {} // Compile-time error. Type notation using this is not supported.
1817  static f2(arg1: number) {
1818    this.n = arg1;  // Compile-time error. Using this inside standalone functions is not supported.
1819  }
1820}
1821
1822function foo(arg1: number) {
1823  this.n = i;       // Compile-time error. Using this inside standalone functions is not supported.
1824}
1825```
1826
1827The keyword `this` used as a primary expression denotes a value that is a reference to the following:
1828
1829* Object for which the instance method is called; or
1830* Object being constructed.
1831
1832The value denoted by `this` in a lambda body and in the surrounding context is the same.
1833
1834## Support for ArkUI
1835
1836This section demonstrates mechanisms that ArkTS provides for creating graphical user interface (GUI) programs. The section is based on the ArkUI declarative framework. ArkUI provides a set of extensions of the standard TypeScript to declaratively describe the GUI of the applications and the interaction between the GUI components.
1837
1838### ArkUI Example
1839
1840The [Example](arkts-mvvm.md#example) provides a complete ArkUI-based application as an illustration of GUI programming capabilities.
1841
1842For more details of the ArkUI features, refer to the ArkUI [Basic Syntax](arkts-basic-syntax-overview.md).
1843
1844<!--no_check-->