Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Common Development Pitfalls and Best Practices for ArkTS in HarmonyOS

Tech 3

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

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.