A `for` statement is executed repeatedly until the specified loop exit condition
A `for` statement is executed repeatedly until the specified loop exit
is `false`. A `for` statement looks as follows:
condition is `false`.
A `for` statement looks as follows:
```typescript
```typescript
for([init];[condition];[update]){
for([init];[condition];[update]){
...
@@ -446,10 +451,15 @@ for ([init]; [condition]; [update]) {
...
@@ -446,10 +451,15 @@ for ([init]; [condition]; [update]) {
When a `for` statement is executed, the following process takes place:
When a `for` statement is executed, the following process takes place:
1. An `init` expression is executed, if any. This expression usually initializes one or more loop counters.
1. An `init` expression is executed, if any. This expression usually
2. The condition is evaluated. If the value of condition is `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 `false`, the `for` loop terminates.
initializes one or more loop counters.
2. The condition is evaluated. If the value of condition is `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 `false`,
then the `for` loop terminates.
3. The statements of the `for` body are executed.
3. The statements of the `for` body are executed.
4. If there is an `update` expression, the `update` expression is executed.
4. If there is an `update` expression, then the `update` expression
is executed.
5. Go back to step 2.
5. Go back to step 2.
Example:
Example:
...
@@ -463,8 +473,9 @@ for (let i = 0; i < 10; i += 2) {
...
@@ -463,8 +473,9 @@ for (let i = 0; i < 10; i += 2) {
### `For-of` Statements
### `For-of` Statements
Use `for-of` statements to iterate over an array or string. A `for-of`
`for-of` statements are used to iterate over an array or string.
statement looks as follows:
A `for-of` statement looks as follows:
```typescript
```typescript
for(forVarofexpression){
for(forVarofexpression){
...
@@ -480,8 +491,10 @@ for (let ch of "a string object") { /* process ch */ }
...
@@ -480,8 +491,10 @@ for (let ch of "a string object") { /* process ch */ }
### `While` Statements
### `While` Statements
A `while` statement has its body statements executed as long as the specified condition
A `while` statement has its body statements executed as long as the
evaluates to `true`. It looks as follows:
specified condition evaluates to `true`.
A `while` statement looks as follows:
```typescript
```typescript
while(condition){
while(condition){
...
@@ -504,8 +517,10 @@ while (n < 3) {
...
@@ -504,8 +517,10 @@ while (n < 3) {
### `Do-while` Statements
### `Do-while` Statements
The `do-while` statements are executed repetitively until the specified
`do-while` statements are executed repetitively until a specified
condition evaluates to false. It looks as follows:
condition evaluates to false.
A `do-while` statement looks as follows:
```typescript
```typescript
do{
do{
...
@@ -526,7 +541,7 @@ do {
...
@@ -526,7 +541,7 @@ do {
### `Break` Statements
### `Break` Statements
Use a `break` statement to terminate any `loop` statement or `switch`.
A `break` statement is used to terminate any `loop` statement or `switch`.
Example:
Example:
...
@@ -558,8 +573,8 @@ label: while (true) {
...
@@ -558,8 +573,8 @@ label: while (true) {
### `Continue` Statements
### `Continue` Statements
A `continue` statement stops the execution of the current loop iteration and
A `continue` statement stops the execution of the current loop iteration
passes control to the next iteration.
and passes control to the next iteration.
Example:
Example:
...
@@ -575,13 +590,13 @@ for (let x = 0; x < 100; x++) {
...
@@ -575,13 +590,13 @@ for (let x = 0; x < 100; x++) {
### `Throw` and `Try` Statements
### `Throw` and `Try` Statements
A `throw` statement is used to throw an exception or error:
A `throw` statement is used to throw an exception or an error:
```typescript
```typescript
thrownewError("this error")
thrownewError("this error")
```
```
A `try` statement is used to catch and handle an exception or error:
A `try` statement is used to catch and handle an exception or an error:
```typescript
```typescript
try{
try{
...
@@ -672,7 +687,7 @@ function hello(name?: string) {
...
@@ -672,7 +687,7 @@ function hello(name?: string) {
Another form contains an expression that specifies a default value.
Another form contains an expression that specifies a default value.
If the corresponding argument to such parameter is omitted in a function call,
If the corresponding argument to such parameter is omitted in a function call,
then this parameter has the default value.
then this parameter’s value is default.
```typescript
```typescript
functionmultiply(n:number,coeff:number=2):number{
functionmultiply(n:number,coeff:number=2):number{
...
@@ -701,7 +716,8 @@ sum(1, 2, 3) // returns 6
...
@@ -701,7 +716,8 @@ sum(1, 2, 3) // returns 6
## Return Types
## Return Types
If function return type can be inferred from its body content then it can be omitted from the function declaration.
If function return type can be inferred from its body content, then it can
The return type of a function that does not need to return a value may be explicitly specified as `void` or omitted altogether. No return statement is needed for such functions.
The 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.
Both notations below are valid:
Both notations below are valid:
...
@@ -722,13 +740,16 @@ function hi2(): void { console.log("hi") }
...
@@ -722,13 +740,16 @@ function hi2(): void { console.log("hi") }
## Function Scope
## Function Scope
Variables and other entities defined in a function are local to the function and cannot be accessed outside.
Variables and other entities defined in a function are local to the function
and cannot be accessed from the outside.
If 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 outer entity.
If 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.
## Function Calls
## Function Calls
Calling a function actually leads to its body execution while arguments of the call are assigned to function parameters.
Calling a function actually leads to the execution of its body, while
the arguments of the call are assigned to the function parameters.
If the function is defined as follows:
If the function is defined as follows:
...
@@ -770,9 +791,11 @@ let sum = (x: number, y: number): number => {
...
@@ -770,9 +791,11 @@ let sum = (x: number, y: number): number => {
}
}
```
```
An arrow function return type may be omitted; in this case it is inferred from the function body.
An arrow function return type can be omitted; in such case, it is inferred
from the function body.
An expression can be specified as an arrow function, making notation shorter, so the following two notations are equivalent:
An expression can be specified as an arrow function to make the notation
shorter, i.e., the following two notations are equivalent:
```typescript
```typescript
letsum1=(x:number,y:number)=>{returnx+y}
letsum1=(x:number,y:number)=>{returnx+y}
...
@@ -781,10 +804,12 @@ let sum2 = (x: number, y: number) => x + y
...
@@ -781,10 +804,12 @@ let sum2 = (x: number, y: number) => x + y
## Closure
## Closure
An arrow function is usually defined inside another function. As an inner function, it can access all variables and functions defined in the outer functions.
An arrow function is usually defined inside another function. As an inner
function, it can access all variables and functions defined in the outer
functions.
To capture the context, an inner function forms a closure of its environment.
To capture the context, an inner function forms a closure of its environment.
The closure allows accessing such inner function outside its own environment.
The closure allows accessing such an inner function outside its own environment.
```typescript
```typescript
functionf():()=>number{
functionf():()=>number{
...
@@ -801,7 +826,10 @@ In the sample above, the arrow function closure captures the `count` variable.
...
@@ -801,7 +826,10 @@ In the sample above, the arrow function closure captures the `count` variable.
## Function Overload Signatures
## Function Overload Signatures
A function can be specified to be called in different ways by writing overload signatures. To do so, several functions headers are written that they have the same name but different signatures, immediately followed by the single implementing function.
A 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.
```typescript
```typescript
functionfoo():void;/* 1st signature */
functionfoo():void;/* 1st signature */
...
@@ -814,13 +842,15 @@ foo() // ok, 1st signature is used
...
@@ -814,13 +842,15 @@ foo() // ok, 1st signature is used
foo("aa")// ok, 2nd signature is used
foo("aa")// ok, 2nd signature is used
```
```
It is an error if two overload signatures have identical parameter lists.
An error occurs if two overload signatures have identical parameter lists.
# Classes
# Classes
A class declaration introduces a new type and defines its fields, methods and constructors.
A class declaration introduces a new type and defines its fields, methods
and constructors.
In the following example, class `Person` is defined, which has fields ‘name’ and ‘surname’, constructor and a method `fullName`:
In the following example, class `Person` is defined, which has fields
‘name’ and ‘surname’, constructor, and a method `fullName`:
```typescript
```typescript
classPerson{
classPerson{
...
@@ -836,21 +866,22 @@ class Person {
...
@@ -836,21 +866,22 @@ class Person {
}
}
```
```
After the class is defined, its instances can be created using the keyword `new`:
After the class is defined, its instances can be created by using
the keyword `new`:
```typescript
```typescript
letp=newPerson("John","Smith")
letp=newPerson("John","Smith")
console.log(p.fullName())
console.log(p.fullName())
```
```
Or an instance can be created using object literals:
or an instance can be created by using object literals:
```typescript
```typescript
classPoint{
classPoint{
x:number=0
x:number=0
y:number=0
y:number=0
}
}
letp:Point={42,42}
letp:Point={x:42,y:42}
```
```
## Fields
## Fields
...
@@ -877,7 +908,7 @@ let p1 = new Person("Alice", 25)
...
@@ -877,7 +908,7 @@ let p1 = new Person("Alice", 25)
letp2=newPerson("Bob",28)
letp2=newPerson("Bob",28)
```
```
To access an instance field, use an instance of the class:
An instance of the class is used to access an instance field:
```typescript
```typescript
p1.name
p1.name
...
@@ -886,10 +917,11 @@ this.name
...
@@ -886,10 +917,11 @@ this.name
### Static Fields
### Static Fields
Use the keyword `static` to declare a field as static. Static fields belong
The keyword `static` is used to declare a field as static. Static fields
to the class itself, and all instances of the class share one static field.
belong to the class itself, and all instances of the class share one static
@@ -989,9 +1028,12 @@ class [extends BaseClassName] [implements listOfInterfaces] {
...
@@ -989,9 +1028,12 @@ class [extends BaseClassName] [implements listOfInterfaces] {
}
}
```
```
The extended class inherits fields and methods from the base class, but not constructors, and can add its own fields and methods as well as override methods defined by the base class.
The extended class inherits fields and methods from the base class, but
not constructors, and can add its own fields and methods as well as override
methods defined by the base class.
The base class is also called ‘parent class’ or ‘superclass’. The extended class also called ‘derived class’ or ‘subclass’.
The base class is also called ‘parent class’ or ‘superclass’.
The extended class also called ‘derived class’ or ‘subclass’.
Example:
Example:
...
@@ -1011,7 +1053,9 @@ class Employee extends Person {
...
@@ -1011,7 +1053,9 @@ class Employee extends Person {
}
}
```
```
A class containing the `implements` clause must implement all methods defined in all listed interfaces, except the methods defined with default implementation.
A class containing the `implements` clause must implement all methods
defined in all listed interfaces, except the methods defined with default
implementation.
```typescript
```typescript
interfaceDateInterface{
interfaceDateInterface{
...
@@ -1027,9 +1071,11 @@ class MyDate implements DateInterface {
...
@@ -1027,9 +1071,11 @@ class MyDate implements DateInterface {
### Access to Super
### Access to Super
The keyword `super` can be used to access instance fields, instance methods and constructors from the super class.
The keyword `super` can be used to access instance fields, instance methods
and constructors from the super class.
It is often used to extend basic functionality of subclass with the required behavior taken from the super class:
It is often used to extend basic functionality of subclass with the required
behavior taken from the super class:
```typescript
```typescript
classRectangle{
classRectangle{
...
@@ -1062,9 +1108,11 @@ class FilledRectangle extends Rectangle {
...
@@ -1062,9 +1108,11 @@ class FilledRectangle extends Rectangle {
### Override Methods
### Override Methods
A subclass may override implementation of a method defined in its superclass.
A subclass can override implementation of a method defined in its superclass.
An overridden method may be marked with the keyword `override`, to improve readability.
An overridden method can be marked with the keyword `override` to improve
An overridden method must have the same types of parameters and same or derived return type as the original method.
readability.
An overridden method must have the same types of parameters, and same or
derived return type as the original method.
```typescript
```typescript
classRectangle{
classRectangle{
...
@@ -1084,7 +1132,10 @@ class Square extends Rectangle {
...
@@ -1084,7 +1132,10 @@ class Square extends Rectangle {
### Method Overload Signatures
### Method Overload Signatures
A method can be specified to can be called in different ways by writing overload signatures. To do so, several method headers are written that have the same name but different signatures, immediately followed by the single implementation method.
A 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.
```typescript
```typescript
classC{
classC{
...
@@ -1099,13 +1150,15 @@ c.foo() // ok, 1st signature is used
...
@@ -1099,13 +1150,15 @@ c.foo() // ok, 1st signature is used
c.foo("aa")// ok, 2nd signature is used
c.foo("aa")// ok, 2nd signature is used
```
```
It is an error if two overload signatures have the same name and identical parameter lists.
An error occurs if two overload signatures have the same name and identical
parameter lists.
## Constructors
## Constructors
A class declaration may contain a constructor that is used to initialize object state.
A class declaration may contain a constructor that is used to initialize
If no constructor is defined, then a default constructor with an empty parameter list is created automatically, for example:
If no constructor is defined, then a default constructor with an empty
parameter list is created automatically, for example:
```typescript
```typescript
classPoint{
classPoint{
...
@@ -1123,11 +1177,13 @@ class Point {
...
@@ -1123,11 +1177,13 @@ class Point {
letp=newPoint()
letp=newPoint()
```
```
In this case the default constructor fills the instance fields with default values for the field types.
In this case the default constructor fills the instance fields with
default values for the field types.
### Constructors in Derived Class
### Constructors in Derived Class
The first statement of a constructor body can use the keyword `super` to explicitly call a constructor of the direct superclass.
The first statement of a constructor body can use the keyword `super`
to explicitly call a constructor of the direct superclass.
```typescript
```typescript
classRectangle{
classRectangle{
...
@@ -1142,11 +1198,16 @@ class Square extends Rectangle {
...
@@ -1142,11 +1198,16 @@ class Square extends Rectangle {
}
}
```
```
If a constructor body does not begin with such an explicit call of a superclass constructor, then the constructor body implicitly begins with a superclass constructor call `super()`.
If a constructor body does not begin with such an explicit call of a
superclass constructor, then the constructor body implicitly begins
with a superclass constructor call `super()`.
### Constructor Overload Signatures
### Constructor Overload Signatures
A constructor can be specified to can be called in different ways by writing overload signatures. To do so, several constructor headers are written that have the same name but different signatures, immediately followed by the single implementation constructor.
A 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.
```typescript
```typescript
classC{
classC{
...
@@ -1160,23 +1221,33 @@ let c1 = new C() // ok, 1st signature is used
...
@@ -1160,23 +1221,33 @@ let c1 = new C() // ok, 1st signature is used
letc2=newC("abc")// ok, 2nd signature is used
letc2=newC("abc")// ok, 2nd signature is used
```
```
It is an error if two overload signatures have the same name and identical parameter lists.
An error occurs if two overload signatures have the same name and
identical parameter lists.
## Visibility Modifiers
## Visibility Modifiers
Both methods and properties of a class can have visibility modifiers.
Both methods and properties of a class can have visibility modifiers.
There are several visibility modifiers: `private`, `protected`,
There are several visibility modifiers:
`public`, and `internal`. The default visibility is `public`.
`internal` allows to limit visibility within the current package.
-`private`,
-`protected`,
-`public`, and
-`internal`.
The default visibility is `public`.
The modifier `internal` allows to limit visibility within
the current package.
### Public Visibility
### Public Visibility
The `public` members (fields, methods, constructors) of a class are visible in any part of the program, where their class is visible.
The `public` members (fields, methods, constructors) of a class are
visible in any part of the program, where their class is visible.
### Private Visibility
### Private Visibility
A `private` member cannot be accessed outside the class in which it is declared, for example:
A `private` member cannot be accessed outside the class it is declared in,
for example:
```typescript
```typescript
classC{
classC{
...
@@ -1193,8 +1264,8 @@ c.y = "b" // compile-time error: 'y' is not visible
...
@@ -1193,8 +1264,8 @@ c.y = "b" // compile-time error: 'y' is not visible
### Protected Visibility
### Protected Visibility
The `protected` modifier acts much like the `private` modifier, but
The modifier `protected` acts much like the modifier `private`, but
`protected` members are also accessible in derived classes, for example:
the `protected` members are also accessible in derived classes, for example:
```typescript
```typescript
classBase{
classBase{
...
@@ -1211,9 +1282,12 @@ class Derived extends Base {
...
@@ -1211,9 +1282,12 @@ class Derived extends Base {
## Object Literals
## Object Literals
An 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 `new` expression as it is more convenient in some cases.
An 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.
A class composite is written as a comma-separated list of name-value pairs enclosed in ‘{’ and ‘}’.
A class composite is written as a comma-separated list of name-value pairs
enclosed in ‘{’ and ‘}’.
```typescript
```typescript
classC{
classC{
...
@@ -1224,7 +1298,9 @@ class C {
...
@@ -1224,7 +1298,9 @@ class C {
letc:C={n:42,s:"foo"}
letc:C={n:42,s:"foo"}
```
```
Due to static typing of the ArkTS the object literals can be used in context where the class or interface type of the object literal can be inferred as in the example above. Other valid cases:
Due 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:
```typescript
```typescript
classC{
classC{
...
@@ -1244,7 +1320,7 @@ function bar(): C {
...
@@ -1244,7 +1320,7 @@ function bar(): C {
}
}
```
```
Type of an array element or a type of a class field also can be used:
The type of an array element or of a class field can also be used:
```typescript
```typescript
classC{
classC{
...
@@ -1254,10 +1330,12 @@ class C {
...
@@ -1254,10 +1330,12 @@ class C {
letcc:C[]=[{n:1,s:"a"},{n:2,s:"b"}]
letcc:C[]=[{n:1,s:"a"},{n:2,s:"b"}]
```
```
### Object Literals of the Record Type
### Object Literals of Record Type
The generic Record<K,V> type is used to map the properties of a type
(Key type) to another type (Value type).
The generic Record<K,V> type is used to map the properties of a type (Key type) to another type (Value type).
A special form of object literal is used to initialize the value of such type:
A special form of an object literal is used to initialize the value of such type:
```typescript
```typescript
letmap:Record<string,number>={
letmap:Record<string,number>={
...
@@ -1283,9 +1361,11 @@ let map: Record<string, PersonInfo> = {
...
@@ -1283,9 +1361,11 @@ let map: Record<string, PersonInfo> = {
# Interfaces
# Interfaces
An interface declaration introduces a new type. Interfaces are a common way of defining contracts between various part of codes.
An interface declaration introduces a new type. Interfaces are a common way
of defining contracts between various part of codes.
Interfaces are used to write polymorphic code, which can be applied to any class instances that implement a particular interface.
Interfaces are used to write polymorphic code, which can be applied to any
class instances that implement a particular interface.
An interface usually contains properties and method headers.
An interface usually contains properties and method headers.
...
@@ -1326,9 +1406,11 @@ class Rectangle implements Area {
...
@@ -1326,9 +1406,11 @@ class Rectangle implements Area {
## Interface Properties
## Interface Properties
An interface property can be in a form of field, getter, setter or both getter and setter.
An interface property can be in a form of field, getter, setter, or both
getter and setter.
A property field is just a shortcut notation of a getter/setter pair, and the following notations are equal:
A property field is just a shortcut notation of a getter/setter pair, and
An extended interface contains all properties and methods of the interface it extends and may also add its own properties and methods.
An extended interface contains all properties and methods of the
interface it extends, and can also add its own properties and methods.
## Interface Visibility Modifiers
## Interface Visibility Modifiers
Properties and methods are `public`.
Properties and methods are `public`.
Only methods with default implementation may be defined as `private`.
Only methods with default implementation can be defined as `private`.
# Generic Types and Functions
# Generic Types and Functions
Generic types and functions allow creating the code capable to work over a variety of types rather than a single one.
Generic types and functions allow creating the code capable to work over a
variety of types rather than a single type.
## Generic Classes and Interfaces
## Generic Classes and Interfaces
A class and an interface can be defined as generics, adding parameters to the type definition, like the type parameter `Element` in the following example:
A class and an interface can be defined as generics, adding parameters to the
type definition, like the type parameter `Element` in the following example:
```typescript
```typescript
classStack<Element>{
classStack<Element>{
publicpop():Element{
publicpop():Element{
// ...
// ...
}
}
publicpush(e:Element){
publicpush(e:Element):void{
// ...
// ...
}
}
}
}
...
@@ -1415,7 +1500,8 @@ let s = new Stack<string>
...
@@ -1415,7 +1500,8 @@ let s = new Stack<string>
s.push("hello")
s.push("hello")
```
```
Compiler ensures type safety while working with generic types and functions. See below
Compiler ensures type safety while working with generic types and functions.
See below:
```typescript
```typescript
lets=newStack<string>
lets=newStack<string>
...
@@ -1424,7 +1510,9 @@ s.push(55) // That will be a compile-time error
...
@@ -1424,7 +1510,9 @@ s.push(55) // That will be a compile-time error
## Generic Constraints
## Generic Constraints
Type parameters of generic types can be bounded. For example, the `Key` type parameter in the `HashMap<Key, Value>` container must have a hash method, i.e., it should be hashable.
Type parameters of generic types can be bounded. For example, the `Key`
type parameter in the `HashMap<Key, Value>` container must have a hash
method, i.e., it must be hashable.
```typescript
```typescript
interfaceHashable{
interfaceHashable{
...
@@ -1438,11 +1526,13 @@ class HasMap<Key extends Hashable, Value> {
...
@@ -1438,11 +1526,13 @@ class HasMap<Key extends Hashable, Value> {
}
}
```
```
In the above example, the `Key` type extends `Hashable`, and all methods of `Hashable` interface can be called for keys.
In the above example, the `Key` type extends `Hashable`, and all methods
of `Hashable` interface can be called for keys.
## Generic Functions
## Generic Functions
Use a generic function to create a more universal code. Consider a function that returns the last element of the array:
Use a generic function to create a more universal code. Consider a function
that returns the last element of the array:
```typescript
```typescript
functionlast(x:number[]):number{
functionlast(x:number[]):number{
...
@@ -1451,7 +1541,8 @@ function last(x: number[]): number {
...
@@ -1451,7 +1541,8 @@ function last(x: number[]): number {
console.log(last([1,2,3]))// output: 3
console.log(last([1,2,3]))// output: 3
```
```
If the same function needs to be defined for any array, define it as generic with a type parameter:
If the same function needs to be defined for any array, then define it as
a generic with a type parameter:
```typescript
```typescript
functionlast<T>(x:T[]):T{
functionlast<T>(x:T[]):T{
...
@@ -1461,7 +1552,7 @@ function last<T>(x: T[]): T {
...
@@ -1461,7 +1552,7 @@ function last<T>(x: T[]): T {
Now, the function can be used with any array.
Now, the function can be used with any array.
In a function call, type argument may be set explicitly or implicitly:
In a function call, type argument can be set explicitly or implicitly:
Type parameters of generic types can have defaults.
Type parameters of generic types can have defaults.
It allows not specifying the actual type arguments but using just the generic type name.
It allows using just the generic type name instead of specifying the actual
type arguments.
Example below illustrates this for both classes and functions.
Example below illustrates this for both classes and functions.
```typescript
```typescript
...
@@ -1497,9 +1589,10 @@ foo<number>()
...
@@ -1497,9 +1589,10 @@ foo<number>()
# Null Safety
# Null Safety
All types in ArkTS by default are non-nullable, so the value of a type cannot be null.
All types in ArkTS by default are non-nullable, so the value of a type
cannot be null.
It is similar to TypeScript behavior in strict null checking mode
It is similar to TypeScript behavior in strict null checking mode
(`strictNullChecks`), but the rules are stricter, and the there is no `undefined` type in ArkTS.
(`strictNullChecks`), but the rules are stricter.
In the example below, all lines cause a compile-time error:
In the example below, all lines cause a compile-time error:
...
@@ -1522,7 +1615,8 @@ if (x != null) { /* do something */ }
...
@@ -1522,7 +1615,8 @@ if (x != null) { /* do something */ }
A postfix operator `!` can be used to assert that its operand is non-null.
A postfix operator `!` can be used to assert that its operand is non-null.
If applied to a null value, the operator throws an error. Otherwise, the type of the value is changed from `T | null` to `T`:
If applied to a null value, the operator throws an error. Otherwise, the
type of the value is changed from `T | null` to `T`:
```typescript
```typescript
letx:number|null=1
letx:number|null=1
...
@@ -1533,12 +1627,15 @@ y = x! + 1 // ok
...
@@ -1533,12 +1627,15 @@ y = x! + 1 // ok
## Null-Coalescing Operator
## Null-Coalescing Operator
The null-coalescing binary operator `??` checks whether the evaluation of the left-hand-side expression is equal to null.
The null-coalescing binary operator `??` checks whether the evaluation
If it is, then the result of the expression is the right-hand-side expression; otherwise, it is the left-hand-side expression.
of the left-hand-side expression is equal to null.
If it is, then the result of the expression is the right-hand-side expression;
otherwise, it is the left-hand-side expression.
In other words, `a ?? b` equals the ternary operator `a != null ? a : b`.
In other words, `a ?? b` equals the ternary operator `a != null ? a : b`.
In the following example, the method `getNick` returns a nickname if it is set; otherwise, empty string is returned:
In the following example, the method `getNick` returns a nickname if it is
set; otherwise, an empty string is returned:
```typescript
```typescript
classPerson{
classPerson{
...
@@ -1552,46 +1649,72 @@ class Person {
...
@@ -1552,46 +1649,72 @@ class Person {
## Optional Chaining
## Optional Chaining
Optional chaining operator `?.` allows writing code where the evaluation stops of an expression that is partially evaluated to `null`.
Optional chaining operator `?.` allows writing code where the evaluation
stops at an expression that is partially evaluated to `null` or `undefined`.
```typescript
```typescript
classPerson{
classPerson{
// ...
nick:string|null=null
spouse:Person|null=null
spouse?:Person
nick:string|null=null
getSpouseNick():string|null{
setSpouse(spouse:Person):void{
this.spouse=spouse
}
getSpouseNick():string|null|undefined{
returnthis.spouse?.nick
returnthis.spouse?.nick
}
}
constructor(nick:string){
this.nick=nick
this.spouse=undefined
}
}
}
```
```
**Note**: that the return type of `getSpouseNick` must be `string | null`, as the method may return null.
**Note**: the return type of `getSpouseNick` must be `string | null | undefined`, as
the method can return null or undefined.
An optional chain may be of any length and contain any number of `?.`
An optional chain can be of any length and contain any number of `?.`
operators.
operators.
In the following sample, the output is a person’s spouse nickname if the person has a spouse, and the spouse has a nickname.
In the following sample, the output is a person’s spouse nickname if that
person has a spouse, and the spouse has a nickname.
Otherwise, the output is `null`:
Otherwise, the output is `undefined`:
```typescript
```typescript
letp:Person=...
classPerson{
console.log(p?.spouse?.nick)
nick:string|null=null
spouse?:Person
constructor(nick:string){
this.nick=nick
this.spouse=undefined
}
}
letp:Person=newPerson("Alice")
console.log(p.spouse?.nick)// print: undefined
```
```
# Modules
# Modules
Programs are organized as sets of compilation units or modules.
Programs are organized as sets of compilation units or modules.
Each 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.
Each 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.
Conversely, a variable, function, class, interface, etc. exported from another module must first be imported to a module.
Conversely, a variable, function, class, interface, etc. exported from
another module must first be imported to a module.
## Export
## Export
A top-level declaration can be exported by using the keyword `export`.
A top-level declaration can be exported by using the keyword `export`.
A declared name that is not exported is considered private and can be used only in the module where it is declared.
A declared name that is not exported is considered private and can be used
only in the module where it is declared.
```typescript
```typescript
exportclassPoint{
exportclassPoint{
...
@@ -1610,16 +1733,21 @@ export function Distance(p1: Point, p2: Point): number {
...
@@ -1610,16 +1733,21 @@ export function Distance(p1: Point, p2: Point): number {
## Import
## Import
Import declarations are used to import entities exported from other modules and provide their bindings in the current module. An import declaration consists of two parts:
Import declarations are used to import entities exported from other modules
and provide their bindings in the current module. An import declaration
consists of two parts:
* Import path that determines the module to import from;
* Import path that determines the module to import from;
* Import bindings that define the set of usable entities in the imported module and the form of use i.e., qualified or unqualified use.
* Import bindings that define the set of usable entities in the imported
module, and the form of use (i.e., qualified or unqualified use).
Import bindings may have several forms.
Import bindings may have several forms.
Let’s assume a module has the path ‘./utils’ and export entities ‘X’ and ‘Y’.
Let’s assume a module has the path ‘./utils’ and export entities ‘X’ and ‘Y’.
An 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`:
An 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`:
```typescript
```typescript
import*asUtilsfrom"./utils"
import*asUtilsfrom"./utils"
...
@@ -1627,7 +1755,8 @@ Utils.X // denotes X from Utils
...
@@ -1627,7 +1755,8 @@ Utils.X // denotes X from Utils
Utils.Y// denotes Y from Utils
Utils.Y// denotes Y from Utils
```
```
An import binding of the form `{ ident1, ..., identN }` binds an exported entity with a specified name, which can be used as a simple name:
An import binding of the form `{ ident1, ..., identN }` binds an exported
entity with a specified name, which can be used as a simple name:
```typescript
```typescript
import{X,Y}from"./utils"
import{X,Y}from"./utils"
...
@@ -1635,7 +1764,8 @@ X // denotes X from Utils
...
@@ -1635,7 +1764,8 @@ X // denotes X from Utils
Y// denotes Y from Utils
Y// denotes Y from Utils
```
```
If a list of identifiers contains aliasing of the form `ident as alias`, then entity `ident` is bound under the name `alias`:
If a list of identifiers contains aliasing of the form `ident as alias`,
then entity `ident` is bound under the name `alias`:
```typescript
```typescript
import{XasZ,Y}from"./utils"
import{XasZ,Y}from"./utils"
...
@@ -1648,12 +1778,17 @@ X // Compile-time error: 'X' is not visible
...
@@ -1648,12 +1778,17 @@ X // Compile-time error: 'X' is not visible
A module can contain any statements at the module level, except `return` ones.
A module can contain any statements at the module level, except `return` ones.
If a module contains a `main` function (program entry point) then top-level statements of the module are executed immediately before the body of this function.
If a module contains a `main` function (program entry point), then
Otherwise, they are executed before execution of any other function of the module.
top-level statements of the module are executed immediately before
the body of this function.
Otherwise, they are executed before execution of any other function
of the module.
## Program Entry Point
## Program Entry Point
An entry point of a program (application) is the top-level `main` function. The `main` function should have either an empty parameter list or a single parameter of `string[]` type.
An entry point of a program (application) is the top-level `main` function.
The `main` function must have either an empty parameter list or a single
parameter of `string[]` type.
```typescript
```typescript
functionmain(){
functionmain(){
...
@@ -1664,16 +1799,16 @@ function main() {
...
@@ -1664,16 +1799,16 @@ function main() {
# Support for ArkUI
# Support for ArkUI
This section demonstrates mechanisms that ArkTS provides for
This section demonstrates mechanisms that ArkTS provides for
creating graphical user interface (GUI) programs. The section is based on the
creating graphical user interface (GUI) programs. The section is based on
ArkUI declarative framework. ArkUI provides a set of extensions of the standard
the ArkUI declarative framework. ArkUI provides a set of extensions of
TypeScript to declaratively describe the GUI of the applications and the interaction
the standard TypeScript to declaratively describe the GUI of the applications
between the GUI components.
and the interaction between the GUI components.
## ArkUI Example
## ArkUI Example
The following example provides a complete ArkUI-based application as an
The following example provides a complete ArkUI-based application as an
illustration of GUI programming capabilities. For more details about ArkUI
illustration of GUI programming capabilities. For more details of the