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