Common Development Pitfalls and Best Practices for ArkTS in HarmonyOS
ArkTS is an optimized evolution of TypeScript, but it enforces stricter syntax and type rules that often cause unexpected compilation errors for developers new to the frameowrk. Below is a collection of common issues and their corrected implementations.
Promise Handling Differences
// Standard TypeScript implementation (two-argument then pattern):
private fetchData() {
this.currentStatus = DataLoadStatus.LOADING
this.fetchPageData(0).then(
(result) => {
this.pageData = result;
if (this.pageData.length === 0) {
this.currentStatus = DataLoadStatus.EMPTY;
} else {
this.currentStatus = DataLoadStatus.SUCCESS;
}
},
(error) => {
this.currentStatus = DataLoadStatus.FAIL;
})
}
// Correct ArkTS implementation (then + catch pattern):
private fetchData() {
this.currentStatus = DataLoadStatus.LOADING
this.fetchPageData(0).then(
(result) => {
this.pageData = result;
if (this.pageData.length === 0) {
this.currentStatus = DataLoadStatus.EMPTY;
} else {
this.currentStatus = DataLoadStatus.SUCCESS;
}
}).catch((error: BusinessError) => {
this.currentStatus = DataLoadStatus.FAIL;
})
}
Explicit Class Property Initialization ArkTS enforces strict undefined safety, requiring all class properties to be either explicitly initialized or marked as optional. This prevents common runtime errors caused by uninitialized properties.
// Unsafe TypeScript pattern:
class User {
username: string // Implicitly undefined
updateUsername(newName: string): void {
this.username = newName
}
getUsername(): string {
// The string return type hides the fact that username can be undefined, leading to hidden runtime risks
return this.username
}
}
let myUser = new User()
// If updateUsername is never called to assign a value:
myUser.getUsername().length; // Throws runtime error: username is undefined
// Safe ArkTS pattern 1: Explicit default initialization
class User {
username: string = ''
updateUsername(newName: string): void {
this.username = newName
}
// Return type is guaranteed to always be string, never null or undefined
getUsername(): string {
return this.username
}
}
let myUser = new User()
// If updateUsername is never called to assign a value:
myUser.getUsername().length; // Returns 0, no runtime exception
// Safe ArkTS pattern 2: Explicit optional properties with compile-time checks
class User {
username?: string // Explicitly marked as possibly undefined
updateUsername(newName: string): void {
this.username = newName
}
// Compile-time error: Return type does not match that username can be undefined
getUsernameWrong(): string {
return this.username
}
getUsername(): string | undefined { // Return type matches the property type declaration
return this.username
}
}
let myUser = new User()
// If updateUsername is never called to assign a value:
// Compile-time error: Compiler catches possible undefined access before deployment
myUser.getUsername().length; // Compilation fails
// Correct usage with optional chaining, passes compilation and runs safely
myUser.getUsername()?.length;
The any Type Is Disallowed in ArkTS
ArkTS requires strict static typing for all values, so the wildcard any type is not supported. All variables must have an explicit declared type.
// Not supported in ArkTS:
let response: any = callApi('hello', 'world');
// Correct approach: Use an explicit typed declaration
let response: ApiResponse = callApi('hello', 'world');
Index Access to Object Properties Is Not Supported
ArkTS does not allow accessing class instance fields via bracket (index) syntax. Dot notation for static property acces is required. Array and typed array index access remains allowed.
class User {
username: string
age: number
email: string
contactNumber: string
constructor(username: string, age: number, email: string, contactNumber: string) {
this.username = username;
this.age = age;
this.email = email;
this.contactNumber = contactNumber;
}
}
let user = new User('John', 30, 'example@example.com', '18000000000');
console.log(user['username']); // Compile-time error
console.log(user.unknownProperty); // Compile-time error
console.log(user.username); // ✅ Correct
let intArray = new Int32Array(1);
intArray[0];// ✅ Array index access is allowed