Classes
Class Declaration
A class declaration introduces a new type and defines its fields, methods, and constructor.
In the following example, we define a Person class with fields name and surname, a constructor, and a method fullName:
class Person {
name: string = '';
surname: string = '';
constructor(n: string, sn: string) {
this.name = n;
this.surname = sn;
}
fullName(): string {
return this.name + ' ' + this.surname;
}
}
After defining a class, you can create instances using the new keyword:
let p = new Person('John', 'Smith');
console.log(p.fullName());
Alternatively, you can create instances using object literals:
class Point {
x: number = 0;
y: number = 0;
}
let p: Point = { x: 42, y: 42 };
Fields
Fields are variables of a certain type declared directly within a class.
A class can have instance fields or static fields.
Instance Fields
Instance fields exist on each instance of the class. Each instance has its own set of instance fields.
To access instance fields, you need to use an instance of the class.
class Person {
name: string = '';
age: number = 0;
constructor(n: string, a: number) {
this.name = n;
this.age = a;
}
getName(): string {
return this.name;
}
}
let p1 = new Person('Alice', 25);
p1.name;
let p2 = new Person('Bob', 28);
p2.getName();
Static Fields
Fields declared with the static keyword are static. Static fields belong to the class itself and are shared among all instances of the class.
To access static fields, you need to use the class name:
class Person {
static numberOfPersons = 0;
constructor() {
// ...
Person.numberOfPersons++;
// ...
}
}
Person.numberOfPersons;
Field Initialization
To reduce runtime errors and improve execution performance,
ArkTS requires that all fields be explicitly initialized either at the time of declaration or in the constructor. This is similar to the strictPropertyInitialization mode in standard TS.
The following code is invalid in ArkTS:
class Person {
name: string; // undefined
setName(n: string): void {
this.name = n;
}
getName(): string {
// Developers using "string" as the return type hides the fact that name could be "undefined".
// A better approach is to annotate the return type as "string | undefined" to inform developers of all possible return values of this API.
return this.name;
}
}
let jack = new Person();
// Assuming no assignment to name in the code, such as calling "jack.setName('Jack')"
jack.getName().length; // Runtime exception: name is undefined
In ArkTS, the code should be written as follows:
class Person {
name: string = '';
setName(n: string): void {
this.name = n;
}
// The type is 'string', which cannot be "null" or "undefined"
getName(): string {
return this.name;
}
}
let jack = new Person();
// Assuming no assignment to name in the code, such as calling "jack.setName('Jack')"
jack.getName().length; // 0, no runtime exception
The following code demonstrates how to handle cases where the name value can be undefined:
class Person {
name?: string; // Can be `undefined`
setName(n: string): void {
this.name = n;
}
// Compile-time error: name can be "undefined", so the return type of this API cannot be solely defined as the string type
getNameWrong(): string {
return this.name;
}
getName(): string | undefined { // Return type matches the type of name
return this.name;
}
}
let jack = new Person();
// Assuming no assignment to name in the code, such as calling "jack.setName('Jack')"
// Compile-time error: The compiler considers the next line of code to potentially access properties of undefined and reports an error
jack.getName().length; // Compilation fails
jack.getName()?.length; // Compilation succeeds, no runtime error
Getters and Setters
Getters and setters can be used to provide controlled access to object properties.
In the following example, a setter is used to prevent the _age property from being set to an invalid value:
class Person {
name: string = '';
private _age: number = 0;
get age(): number { return this._age; }
set age(x: number) {
if (x < 0) {
throw Error('Invalid age argument');
}
this._age = x;
}
}
let p = new Person();
p.age; // Outputs 0
p.age = -42; // Setting an invalid age value throws an error
You can define either a getter or a setter in a class.
Top comments (0)