ArkTS语言核心

What — 是什么

ArkTS 是华为基于 TypeScript 扩展的编程语言,是鸿蒙(HarmonyOS)应用开发的官方语言,通过静态类型增强、AOT 编译和限制动态特性,实现了比标准 TypeScript 更高的运行时性能和更严格的类型安全。

核心概念:

  • ArkTS 语言:基于 TypeScript 的高性能静态类型语言,鸿蒙应用层唯一官方开发语言
  • 方舟编译器(Ark Compiler):华为自研的 AOT 编译器,将 ArkTS 编译为高效本地代码
  • 静态类型增强:比标准 TS 更严格的类型约束,禁止 any、限制动态特性
  • 声明式 UI 装饰器@Component@Entry@State 等装饰器驱动 ArkUI 声明式开发
  • 空安全机制:可选链 ?.、非空断言 !、空值合并 ?? 的系统性空值防护

ArkTS 在鸿蒙架构中的位置:

┌─────────────────────────────────────────────────────────────────┐
│                      HarmonyOS 应用架构                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                 应用层 (Application)                      │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  │   │
│  │  │   ArkTS 代码  │  │  ArkUI 声明式 │  │  业务逻辑     │  │   │
│  │  │  (开发语言)    │  │  (UI 框架)    │  │  (数据/网络)  │  │   │
│  │  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘  │   │
│  └─────────┼────────────────┼────────────────┼────────────┘   │
│            │                │                │                 │
│  ┌─────────▼────────────────▼────────────────▼────────────┐   │
│  │             方舟编译器 (Ark Compiler / AOT)              │   │
│  │      静态类型分析 → 优化 → 生成高效本地机器码              │   │
│  └──────────────────────────┬────────────────────────────┘   │
│                             │                                 │
│  ┌──────────────────────────▼────────────────────────────┐   │
│  │               ArkTS 运行时 (Ark Runtime)                │   │
│  │     内存管理 / GC / TaskPool / Worker / 类型系统支持     │   │
│  └──────────────────────────┬────────────────────────────┘   │
│                             │                                 │
│  ┌──────────────────────────▼────────────────────────────┐   │
│  │              HarmonyOS 系统服务层                        │   │
│  │     Ability / 分布式 / 图形 / 网络 / 文件 / 安全         │   │
│  └────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

ArkTS 语法体系总览:

┌───────────────────────────────────────────────────────┐
│                   ArkTS 语言体系                        │
├─────────────┬─────────────┬──────────────┬────────────┤
│  类型系统    │  面向对象    │  函数式特性    │  并发模型   │
├─────────────┼─────────────┼──────────────┼────────────┤
│ 基础类型     │ class       │ 箭头函数      │ Promise    │
│ 联合/交叉    │ abstract    │ 函数重载      │ async/await│
│ 字面量类型   │ interface   │ 闭包         │ TaskPool   │
│ 泛型/约束    │ extends     │ 高阶函数      │ Worker     │
│ 枚举         │ implements  │ 剩余参数      │            │
│ 类型守卫     │ 装饰器      │ 可选/默认参数  │            │
│ 空安全       │ 模块系统     │              │            │
└─────────────┴─────────────┴──────────────┴────────────┘

Why — 为什么

适用场景:

  • 所有鸿蒙应用的开发(ArkTS 是鸿蒙应用层唯一官方开发语言)
  • 需要跨设备(手机/平板/手表/车机/PC)运行的鸿蒙应用
  • 对性能有较高要求的移动端应用(AOT 编译提供接近原生的性能)
  • 需要声明式 UI 开发范式的场景(ArkUI 框架基于 ArkTS)

ArkTS 与 TypeScript 的关系和差异:

维度TypeScriptArkTS
定位JavaScript 的超集,通用脚本语言鸿蒙官方开发语言,面向应用开发
类型严格度可选严格模式,允许 any强制严格模式,禁止 any
动态特性允许 eval/with/动态属性限制或禁止动态特性
编译方式转译为 JavaScript(JIT 为主)AOT 编译为本地机器码
运行时V8 / Node.js 等 JS 引擎方舟运行时(Ark Runtime)
装饰器实验性支持核心特性,UI 框架深度依赖
空安全可选 strictNullChecks语言层面强制空安全
模块系统ES Modules + CommonJSES Modules(推荐静态导入)
性能依赖 JIT 优化AOT 编译,性能接近原生
生态npm 海量包鸿蒙 SDK + ohpm 仓库

ArkTS 对 TypeScript 动态特性的限制:

限制项TypeScript 行为ArkTS 限制原因
any 类型允许使用禁止使用any 绕过类型检查,AOT 无法优化
eval()允许执行动态代码禁止使用动态代码无法静态分析
with 语句允许使用禁止使用作用域不明确,无法静态分析
动态属性访问obj[expr] 任意键限制动态属性AOT 需要确定对象形状
原型链修改Object.prototype.xxx禁止修改内置原型破坏类型稳定性
delete 操作符可删除任意属性限制使用改变对象形状影响性能
as any 断言允许任意断言禁止 as anyany 禁用
索引签名[key: string]: any受限使用运行时类型不确定

优缺点:

  • ✅ 优点:
    • AOT 编译提供接近原生的运行时性能
    • 严格的类型系统减少运行时错误
    • 声明式装饰器让 UI 开发更简洁高效
    • 与鸿蒙系统深度集成,API 访问无障碍
    • TypeScript 开发者上手成本低
  • ❌ 缺点:
    • 动态特性受限,部分 TS 写法需改造
    • 生态尚在发展,第三方库不如 npm 丰富
    • 强制类型注解增加编码量
    • 仅限鸿蒙平台,无跨平台能力

与同类语言的对比:

维度ArkTSDart (Flutter)Swift (iOS)Kotlin (Android)
基础语言TypeScript自研自研基于 JVM
类型系统静态强类型+泛型静态强类型+泛型静态强类型+泛型静态强类型+泛型
编译方式AOTAOT/JITAOTAOT/Kotlin Native
空安全强制强制(Sound Null Safety)强制(Optional)强制
UI 范式声明式(ArkUI)声明式(Widget)声明式(SwiftUI)声明式(Compose)
跨平台鸿蒙多设备6平台Apple 生态Android/JVM
动态特性严格限制严格限制无动态特性有限反射
学习曲线(前端)低(TS相似)中(需学新语法)高(全新语法)中(类TS语法)

How — 怎么用

ArkTS 与 TypeScript 的差异详解

1. 禁止 any 类型

// ❌ TypeScript 写法 — ArkTS 中不允许
let data: any = fetchData();
let result = (data as any).value;

// ✅ ArkTS 正确写法 — 使用具体类型
interface ApiResponse {
  code: number;
  value: string;
  message: string;
}

let data: ApiResponse = fetchData();
let result: string = data.value;

// ✅ 如果类型真的未知,使用 unknown 并做类型收窄
let data: unknown = parseInput(rawStr);
if (typeof data === 'object' && data !== null && 'value' in data) {
  let result: string = (data as ApiResponse).value;
}

2. 禁止 eval 和 with

// ❌ TypeScript 写法 — ArkTS 中不允许
eval("console.log('hello')");
with (obj) { console.log(name); } // 动态作用域

// ✅ ArkTS 正确写法 — 使用函数和明确的作用域
function logMessage(msg: string): void {
  console.log(msg);
}
logMessage('hello');

console.log(obj.name); // 明确的属性访问

3. 强制类型注解

// ❌ TypeScript 写法 — 隐式 any
function process(input) {  // 参数缺少类型注解
  return input.length;
}

// ✅ ArkTS 正确写法 — 显式类型注解
function process(input: string): number {
  return input.length;
}

// ❌ 隐式 any 的变量声明
let items = [];  // TypeScript 推断为 any[]

// ✅ ArkTS 必须提供类型
let items: string[] = [];
let count: number = 0;

4. 限制动态属性访问

// ❌ TypeScript 写法 — ArkTS 中受限
const key = Math.random() > 0.5 ? 'name' : 'age';
const value = obj[key]; // 动态键访问

// ✅ ArkTS 正确写法 — 使用类型守卫或映射类型
type UserKey = 'name' | 'age';
function getValue(obj: User, key: UserKey): string | number {
  if (key === 'name') {
    return obj.name;
  }
  return obj.age;
}

// ✅ 或使用 Record 类型
const config: Record<string, string> = {
  'host': 'localhost',
  'port': '8080'
};
const host: string = config['host']; // Record 允许索引访问

变量声明与类型系统

基础类型

// ===== 基础类型声明 =====
let username: string = 'Alice';
let age: number = 25;
let isActive: boolean = true;

// ArkTS 基础类型与 TypeScript 一致
let message: string = 'Hello HarmonyOS';
let count: number = 100;
let flag: boolean = false;

// ===== 数组类型 =====
let numbers: number[] = [1, 2, 3, 4, 5];
let names: Array<string> = ['Alice', 'Bob', 'Charlie']; // 泛型写法

// ===== 联合类型 =====
let id: string | number = 'A001';
id = 1001; // 也可以赋值为 number

type Status = 'pending' | 'active' | 'completed' | 'cancelled';
let orderStatus: Status = 'pending';

// ===== 交叉类型 =====
type Timestamped = {
  createdAt: string;
  updatedAt: string;
};

type Identifiable = {
  id: string;
};

type Entity = Identifiable & Timestamped;
// Entity 同时具有 id, createdAt, updatedAt

let user: Entity = {
  id: 'U001',
  createdAt: '2026-01-01',
  updatedAt: '2026-05-11'
};

// ===== 字面量类型 =====
type Direction = 'left' | 'right' | 'up' | 'down';
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;

// 字面量类型与联合类型结合 — 精确约束
type EventName = 'click' | 'hover' | 'focus' | 'blur';
function onEvent(name: EventName, handler: () => void): void {
  console.log(`Registered ${name} event`);
}

// ===== const 与 let =====
const API_BASE: string = 'https://api.harmonyos.com'; // 不可重新赋值
let currentPage: number = 1; // 可重新赋值

// const 推断为字面量类型(与 TS 一致)
const direction = 'left'; // 推断为 'left' 而非 string

类型别名与内联类型

// ===== type 别名 =====
type Point = {
  x: number;
  y: number;
};

type Callback = (data: string) => void;

type Nullable<T> = T | null; // 泛型类型别名

// ===== 实战:表单字段定义 =====
type FormField = {
  name: string;
  label: string;
  type: 'text' | 'number' | 'email' | 'password' | 'select';
  required: boolean;
  placeholder?: string;       // 可选属性
  readonly options?: string[]; // 仅当 type === 'select' 时需要
};

const loginFields: FormField[] = [
  { name: 'email', label: '邮箱', type: 'email', required: true },
  { name: 'password', label: '密码', type: 'password', required: true },
];

接口与类

接口(interface)

// ===== 基础接口 =====
interface User {
  id: string;
  name: string;
  email: string;
  avatar?: string;        // 可选属性
  readonly role: string;  // 只读属性
}

// 接口扩展
interface AdminUser extends User {
  permissions: string[];
  level: number;
}

// 多接口扩展
interface Loggable {
  log(): void;
}

interface Serializable {
  serialize(): string;
}

interface Storable extends Loggable, Serializable {
  storageKey: string;
}

// ===== 接口实现 =====
class ConsoleLogger implements Loggable {
  log(): void {
    console.log('ConsoleLogger active');
  }
}

// ===== 接口定义函数形状 =====
interface SearchFunc {
  (source: string, term: string): boolean;
}

const containsTerm: SearchFunc = (source, term) => {
  return source.includes(term);
};

// ===== 实战:API 响应接口 =====
interface ApiResponse<T> {
  code: number;
  message: string;
  data: T;
  timestamp: number;
}

interface UserInfo {
  id: string;
  name: string;
  avatar: string;
  vipLevel: number;
}

// 使用泛型接口
function parseResponse(json: string): ApiResponse<UserInfo> {
  const parsed = JSON.parse(json) as ApiResponse<UserInfo>;
  return parsed;
}

类(class)

// ===== 基础类定义 =====
class Person {
  // ArkTS 中类的属性必须显式声明
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet(): string {
    return `Hello, I'm ${this.name}, ${this.age} years old.`;
  }
}

const alice = new Person('Alice', 25);
console.log(alice.greet());

// ===== 访问修饰符 =====
class BankAccount {
  private balance: number;     // 仅类内部访问
  protected owner: string;     // 类及子类访问
  public accountNo: string;    // 任何位置可访问
  readonly createdAt: string;  // 只读,初始化后不可修改

  constructor(owner: string, accountNo: string, balance: number) {
    this.owner = owner;
    this.accountNo = accountNo;
    this.balance = balance;
    this.createdAt = new Date().toISOString();
  }

  // getter / setter
  get currentBalance(): number {
    return this.balance;
  }

  set deposit(amount: number) {
    if (amount > 0) {
      this.balance += amount;
    }
  }

  // 私有方法
  private validateAmount(amount: number): boolean {
    return amount > 0 && this.balance >= amount;
  }

  withdraw(amount: number): boolean {
    if (this.validateAmount(amount)) {
      this.balance -= amount;
      return true;
    }
    return false;
  }
}

// ===== 继承 =====
class Animal {
  constructor(public name: string, public sound: string) {}

  speak(): string {
    return `${this.name} says ${this.sound}`;
  }
}

class Dog extends Animal {
  constructor(name: string) {
    super(name, 'Woof');
  }

  fetch(item: string): string {
    return `${this.name} fetches the ${item}`;
  }
}

class Cat extends Animal {
  constructor(name: string) {
    super(name, 'Meow');
  }

  purr(): string {
    return `${this.name} is purring`;
  }
}

// ===== 抽象类 =====
abstract class Shape {
  abstract area(): number;            // 抽象方法,子类必须实现
  abstract perimeter(): number;

  describe(): string {                // 具体方法,子类可继承
    return `Area: ${this.area()}, Perimeter: ${this.perimeter()}`;
  }
}

class Circle extends Shape {
  constructor(public radius: number) {
    super();
  }

  area(): number {
    return Math.PI * this.radius * this.radius;
  }

  perimeter(): number {
    return 2 * Math.PI * this.radius;
  }
}

class Rectangle extends Shape {
  constructor(public width: number, public height: number) {
    super();
  }

  area(): number {
    return this.width * this.height;
  }

  perimeter(): number {
    return 2 * (this.width + this.height);
  }
}

// 多态
const shapes: Shape[] = [
  new Circle(5),
  new Rectangle(4, 6),
];
shapes.forEach(s => console.log(s.describe()));

// ===== implements 接口 =====
interface Printable {
  print(): void;
}

interface Comparable<T> {
  compareTo(other: T): number;
}

class Student implements Printable, Comparable<Student> {
  constructor(
    public id: string,
    public name: string,
    public score: number
  ) {}

  print(): void {
    console.log(`[${this.id}] ${this.name}: ${this.score}`);
  }

  compareTo(other: Student): number {
    return this.score - other.score; // 升序
  }
}

枚举与类型守卫

枚举(enum)

// ===== 数字枚举 =====
enum Direction {
  Up,      // 0
  Down,    // 1
  Left,    // 2
  Right    // 3
}

let dir: Direction = Direction.Up;
console.log(Direction[0]); // 'Up' — 反向映射

// ===== 字符串枚举(推荐) =====
enum HttpStatus {
  OK = '200',
  Created = '201',
  BadRequest = '400',
  Unauthorized = '401',
  NotFound = '404',
  InternalError = '500'
}

function handleStatus(status: HttpStatus): string {
  switch (status) {
    case HttpStatus.OK:
      return '请求成功';
    case HttpStatus.NotFound:
      return '资源未找到';
    case HttpStatus.InternalError:
      return '服务器错误';
    default:
      return '未知状态';
  }
}

// ===== const enum(更高效,编译时内联) =====
const enum Color {
  Red = '#FF0000',
  Green = '#00FF00',
  Blue = '#0000FF'
}

let bgColor: Color = Color.Red; // 编译后直接替换为 '#FF0000'

// ===== 实战:应用状态枚举 =====
enum AppState {
  Initializing = 'INITIALIZING',
  Loading = 'LOADING',
  Ready = 'READY',
  Error = 'ERROR',
  Background = 'BACKGROUND'
}

function onAppStateChanged(newState: AppState): void {
  switch (newState) {
    case AppState.Initializing:
      console.log('应用初始化中...');
      break;
    case AppState.Loading:
      console.log('加载数据...');
      break;
    case AppState.Ready:
      console.log('应用就绪');
      break;
    case AppState.Error:
      console.log('发生错误');
      break;
    case AppState.Background:
      console.log('应用进入后台');
      break;
  }
}

// ===== 枚举与联合字面量的选择 =====
// ArkTS 推荐场景:
// - 需要运行时值和反向映射 → enum
// - 仅需编译期类型约束 → 联合字面量(更轻量)
type Theme = 'light' | 'dark' | 'auto'; // 比 enum 更简洁

类型守卫(Type Guard)

// ===== typeof 守卫 =====
function formatValue(value: string | number): string {
  if (typeof value === 'string') {
    return value.trim(); // TypeScript 知道这里是 string
  }
  return value.toFixed(2); // TypeScript 知道这里是 number
}

// ===== instanceof 守卫 =====
class SuccessResult {
  constructor(public data: string) {}
}

class ErrorResult {
  constructor(public message: string) {}
}

type Result = SuccessResult | ErrorResult;

function handleResult(result: Result): string {
  if (result instanceof SuccessResult) {
    return `Success: ${result.data}`;
  }
  return `Error: ${result.message}`;
}

// ===== in 操作符守卫 =====
interface Car {
  wheels: number;
  drive(): void;
}

interface Boat {
  sail(): void;
}

function operate(vehicle: Car | Boat): void {
  if ('drive' in vehicle) {
    vehicle.drive();
  } else {
    vehicle.sail();
  }
}

// ===== 自定义类型守卫(is 谓词) =====
interface Dog {
  breed: string;
  bark(): void;
}

interface Cat {
  color: string;
  purr(): void;
}

function isDog(pet: Dog | Cat): pet is Dog {
  return (pet as Dog).bark !== undefined;
}

function interact(pet: Dog | Cat): void {
  if (isDog(pet)) {
    pet.bark();    // TypeScript 知道 pet 是 Dog
  } else {
    pet.purr();    // TypeScript 知道 pet 是 Cat
  }
}

// ===== 可辨识联合(Discriminated Union) =====
interface CircleShape {
  kind: 'circle';   // 可辨识属性
  radius: number;
}

interface RectShape {
  kind: 'rectangle';
  width: number;
  height: number;
}

interface TriangleShape {
  kind: 'triangle';
  base: number;
  height: number;
}

type Shape2D = CircleShape | RectShape | TriangleShape;

function calculateArea(shape: Shape2D): number {
  switch (shape.kind) {
    case 'circle':
      return Math.PI * shape.radius ** 2;  // shape 自动收窄为 CircleShape
    case 'rectangle':
      return shape.width * shape.height;    // shape 自动收窄为 RectShape
    case 'triangle':
      return 0.5 * shape.base * shape.height;
  }
}

// ===== 穷尽检查 =====
function assertNever(x: never): never {
  throw new Error(`Unexpected value: ${x}`);
}

function describeShape(shape: Shape2D): string {
  switch (shape.kind) {
    case 'circle':
      return `Circle with radius ${shape.radius}`;
    case 'rectangle':
      return `Rectangle ${shape.width}x${shape.height}`;
    case 'triangle':
      return `Triangle base=${shape.base} height=${shape.height}`;
    default:
      return assertNever(shape); // 如果遗漏 case,编译报错
  }
}

泛型与泛型约束

泛型基础

// ===== 泛型函数 =====
function identity<T>(value: T): T {
  return value;
}

const num = identity<number>(42);       // 显式指定类型参数
const str = identity('hello');          // 类型推断为 string

// ===== 泛型接口 =====
interface Repository<T> {
  findById(id: string): T | null;
  findAll(): T[];
  save(entity: T): T;
  delete(id: string): boolean;
}

// ===== 泛型类 =====
class DataStore<T> {
  private items: T[] = [];

  add(item: T): void {
    this.items.push(item);
  }

  get(index: number): T | undefined {
    return this.items[index];
  }

  getAll(): T[] {
    return [...this.items]; // 返回副本
  }

  find(predicate: (item: T) => boolean): T | undefined {
    return this.items.find(predicate);
  }

  count(): number {
    return this.items.length;
  }
}

// 使用泛型类
const userStore = new DataStore<User>();
userStore.add({ id: '1', name: 'Alice', email: 'alice@test.com', role: 'admin' });

const numberStore = new DataStore<number>();
numberStore.add(1);
numberStore.add(2);

泛型约束

// ===== extends 约束 =====
interface HasLength {
  length: number;
}

// 约束 T 必须有 length 属性
function getLength<T extends HasLength>(item: T): number {
  return item.length;
}

getLength('hello');     // string 有 length ✓
getLength([1, 2, 3]);  // Array 有 length ✓
// getLength(123);      // number 无 length ✗

// ===== keyof 约束 =====
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const person = { name: 'Alice', age: 25, city: 'Shanghai' };
const name = getProperty(person, 'name');   // string
const age = getProperty(person, 'age');     // number
// getProperty(person, 'email');            // 编译错误,'email' 不是 person 的属性

// ===== 多泛型约束 =====
interface Identifiable {
  id: string;
}

interface Timestamped {
  createdAt: number;
}

// T 必须同时满足 Identifiable 和 Timestamped
function mergeAndSort<T extends Identifiable & Timestamped>(items: T[]): T[] {
  return items.sort((a, b) => a.createdAt - b.createdAt);
}

// ===== new() 约束 — 工厂模式 =====
function createInstance<T>(ctor: new () => T): T {
  return new ctor();
}

class Config {
  theme: string = 'light';
  lang: string = 'zh-CN';
}

const config = createInstance(Config); // config: Config

// ===== 实战:通用 API 请求函数 =====
interface ApiError {
  code: number;
  message: string;
}

async function request<T>(
  url: string,
  options?: {
    method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
    body?: Record<string, Object>;
    headers?: Record<string, string>;
  }
): Promise<T> {
  const method = options?.method ?? 'GET';
  // 实际项目中使用 @ohos.net.http 发起请求
  console.log(`${method} ${url}`);
  return {} as T; // 简化示意
}

// 使用
interface ProductList {
  items: Product[];
  total: number;
}

interface Product {
  id: string;
  name: string;
  price: number;
}

const products = await request<ProductList>('/api/products');

泛型工具类型

// ===== 内置工具类型(与 TypeScript 一致) =====

// Partial — 所有属性变为可选
type PartialUser = Partial<User>;

// Required — 所有属性变为必选
type RequiredConfig = Required<{
  host?: string;
  port?: number;
}>;

// Pick — 选取部分属性
type UserBasic = Pick<User, 'id' | 'name'>;

// Omit — 排除部分属性
type UserWithoutRole = Omit<User, 'role'>;

// Record — 键值映射
type PageMap = Record<string, { title: string; path: string }>;

// Exclude / Extract — 联合类型过滤
type StatusValues = 'active' | 'inactive' | 'pending' | 'deleted';
type ActiveStatus = Extract<StatusValues, 'active' | 'pending'>;
type NonDeleted = Exclude<StatusValues, 'deleted'>;

// ReturnType — 提取函数返回类型
function createUser() {
  return { id: '1', name: 'Alice' };
}
type CreatedUser = ReturnType<typeof createUser>; // { id: string; name: string }

// ===== 自定义工具类型 =====
type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

type Nullable<T> = T | null;

type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

// 实战:表单数据类型(所有字段变为可选且可空)
type FormData<T> = DeepPartial<Nullable<T>>;

函数

函数声明与参数

// ===== 函数声明方式 =====

// 函数声明
function add(a: number, b: number): number {
  return a + b;
}

// 函数表达式
const multiply = function(a: number, b: number): number {
  return a * b;
};

// 箭头函数(ArkUI 中最常用)
const divide = (a: number, b: number): number => a / b;

// ===== 可选参数 =====
function buildGreeting(name: string, title?: string): string {
  if (title) {
    return `Hello, ${title} ${name}`;
  }
  return `Hello, ${name}`;
}

buildGreeting('Alice');              // 'Hello, Alice'
buildGreeting('Alice', 'Dr.');       // 'Hello, Dr. Alice'

// ===== 默认参数 =====
function createUser(
  name: string,
  role: string = 'user',
  active: boolean = true
): User {
  return { id: Date.now().toString(), name, email: '', role };
}

createUser('Alice');                  // role='user', active=true
createUser('Bob', 'admin');           // role='admin', active=true
createUser('Carol', 'editor', false); // 全部指定

// ===== 剩余参数 =====
function sum(...numbers: number[]): number {
  return numbers.reduce((acc, n) => acc + n, 0);
}

sum(1, 2, 3);       // 6
sum(10, 20, 30, 40); // 100

function formatLog(level: string, ...messages: string[]): string {
  const timestamp = new Date().toISOString();
  return `[${timestamp}] [${level}] ${messages.join(' ')}`;
}

formatLog('INFO', 'Server', 'started', 'on', 'port', '8080');

// ===== 参数解构 =====
interface SearchOptions {
  query: string;
  page?: number;
  pageSize?: number;
  sortBy?: string;
}

function search({ query, page = 1, pageSize = 20, sortBy = 'relevance' }: SearchOptions): string[] {
  console.log(`Searching "${query}", page ${page}, size ${pageSize}, sort by ${sortBy}`);
  return [];
}

函数重载

// ===== 函数重载 =====
// ArkTS 支持函数重载,先声明重载签名,再实现

function parseInput(input: string): number;
function parseInput(input: number): string;
function parseInput(input: string | number): string | number {
  if (typeof input === 'string') {
    return parseInt(input, 10);
  }
  return input.toString();
}

const numResult: number = parseInput('42');
const strResult: string = parseInput(42);

// ===== 实战:重载实现不同参数组合 =====
function createElement(tag: string): Element;
function createElement(tag: string, attrs: Record<string, string>): Element;
function createElement(tag: string, attrs: Record<string, string>, children: Element[]): Element;
function createElement(
  tag: string,
  attrs?: Record<string, string>,
  children?: Element[]
): Element {
  const el: Element = { tag, attrs: attrs ?? {}, children: children ?? [] };
  return el;
}

// ===== 重载与联合类型的取舍 =====
// 如果只是参数类型不同,联合类型更简洁
function process(input: string | number): string {
  if (typeof input === 'string') return input.toUpperCase();
  return input.toFixed(2);
}

// 如果返回值类型随参数变化,使用重载
function getItem(index: number): string;
function getItem(key: string): string | undefined;
function getItem(keyOrIndex: string | number): string | undefined {
  // 实现...
  return undefined;
}

高阶函数与闭包

// ===== 高阶函数 =====
type Transformer<T, U> = (item: T) => U;

function mapArray<T, U>(arr: T[], transform: Transformer<T, U>): U[] {
  const result: U[] = [];
  for (const item of arr) {
    result.push(transform(item));
  }
  return result;
}

const lengths = mapArray(['hello', 'world'], s => s.length); // [5, 5]

// ===== 闭包 =====
function createCounter(initial: number = 0): {
  increment: () => number;
  decrement: () => number;
  value: () => number;
} {
  let count = initial;
  return {
    increment: () => ++count,
    decrement: () => --count,
    value: () => count,
  };
}

const counter = createCounter(10);
counter.increment(); // 11
counter.increment(); // 12
counter.decrement(); // 11
counter.value();     // 11

// ===== 函数柯里化 =====
function curry<T, U, V>(fn: (a: T, b: U) => V): (a: T) => (b: U) => V {
  return (a: T) => (b: U) => fn(a, b);
}

const add = (a: number, b: number) => a + b;
const add5 = curry(add)(5);
console.log(add5(3));  // 8
console.log(add5(10)); // 15

模块系统

静态导入导出

// ===== logger.ets — 工具模块 =====

// 命名导出
export enum LogLevel {
  Debug = 'DEBUG',
  Info = 'INFO',
  Warn = 'WARN',
  Error = 'ERROR'
}

export function log(level: LogLevel, message: string): void {
  console.log(`[${level}] ${message}`);
}

export function debug(message: string): void {
  log(LogLevel.Debug, message);
}

export function info(message: string): void {
  log(LogLevel.Info, message);
}

// 默认导出
export default class Logger {
  private prefix: string;

  constructor(prefix: string) {
    this.prefix = prefix;
  }

  log(message: string): void {
    console.log(`[${this.prefix}] ${message}`);
  }
}

// ===== 命名空间内导出(重新导出) =====
export { LogLevel as LevelType } from './logger';
// ===== app.ets — 使用模块 =====

// 导入默认导出
import Logger from './logger';

// 导入命名导出
import { LogLevel, log, info, debug } from './logger';

// 重命名导入
import { LogLevel as Level } from './logger';

// 全部导入
import * as LoggerModule from './logger';

// 使用
const logger = new Logger('MyApp');
logger.log('Application started');

log(LogLevel.Info, 'System initialized');
debug('Debug mode active');

const currentLevel: Level = Level.Info;

动态导入

// ===== 动态导入 — 按需加载模块 =====

async function loadHeavyModule(): Promise<void> {
  // 动态 import 返回 Promise
  const heavyModule = await import('./heavy-module');
  heavyModule.doWork();
}

// ===== 实战:路由级别的动态导入 =====
interface RouteConfig {
  path: string;
  load: () => Promise<{ default: object }>;
}

const routes: RouteConfig[] = [
  { path: '/home', load: () => import('./pages/HomePage') },
  { path: '/profile', load: () => import('./pages/ProfilePage') },
  { path: '/settings', load: () => import('./pages/SettingsPage') },
];

async function navigate(path: string): Promise<void> {
  const route = routes.find(r => r.path === path);
  if (route) {
    const page = await route.load();
    console.log(`Loaded page for ${path}`);
  }
}

装饰器(Decorators)

装饰器是 ArkTS/ArkUI 的核心机制,用于声明式 UI 开发。

装饰器体系总览

┌─────────────────────────────────────────────────────────────────┐
│                    ArkUI 装饰器体系                               │
├───────────────┬─────────────────────────────────────────────────┤
│  类别          │  装饰器                                         │
├───────────────┼─────────────────────────────────────────────────┤
│  组件定义      │  @Entry, @Component, @Preview                   │
├───────────────┼─────────────────────────────────────────────────┤
│  状态管理      │  @State, @Prop, @Link, @Provide, @Consume      │
│               │  @StorageLink, @StorageProp                     │
├───────────────┼─────────────────────────────────────────────────┤
│  观察与联动    │  @Watch, @Observed, @ObjectLink                 │
├───────────────┼─────────────────────────────────────────────────┤
│  UI 构建       │  @Builder, @Extend, @Styles                    │
├───────────────┼─────────────────────────────────────────────────┤
│  动画          │  @AnimatableExtend                             │
└───────────────┴─────────────────────────────────────────────────┘

@Entry 与 @Component

// @Entry — 标记页面入口组件,一个页面只有一个 @Entry
// @Component — 标记自定义组件,所有 UI 组件必须加此装饰器

@Entry
@Component
struct IndexPage {
  // 组件状态
  @State message: string = 'Hello HarmonyOS';
  @State count: number = 0;

  // build 方法 — 必须实现,描述 UI 结构
  build() {
    Column() {
      Text(this.message)
        .fontSize(24)
        .fontWeight(FontWeight.Bold)

      Text(`Count: ${this.count}`)
        .fontSize(18)
        .margin({ top: 10 })

      Button('Increment')
        .onClick(() => {
          this.count++;
        })
        .margin({ top: 10 })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

状态管理装饰器

// ===== @State — 组件内部状态,变化触发 UI 刷新 =====
@Component
struct StateDemo {
  @State count: number = 0;
  @State user: User = { id: '1', name: 'Alice', email: 'a@b.com', role: 'admin' };
  @State items: string[] = ['Apple', 'Banana'];

  build() {
    Column() {
      Text(`Count: ${this.count}`)
      Button('+1')
        .onClick(() => this.count++) // @State 变化 → UI 自动更新

      Text(`User: ${this.user.name}`)
      Button('Change Name')
        .onClick(() => {
          this.user.name = 'Bob'; // @State 嵌套属性变化也会触发更新
        })
    }
  }
}

// ===== @Prop — 父组件单向传递,子组件只读 =====
@Component
struct ChildComponent {
  @Prop title: string = '';     // 单向数据流,子组件不能修改
  @Prop count: number = 0;

  build() {
    Column() {
      Text(this.title)
      Text(`Count: ${this.count}`)
    }
  }
}

// ===== @Link — 父子组件双向绑定 =====
@Component
struct CounterComponent {
  @Link value: number;  // 双向绑定,修改会同步回父组件

  build() {
    Row() {
      Button('-').onClick(() => this.value--)
      Text(`${this.value}`).margin({ left: 10, right: 10 })
      Button('+').onClick(() => this.value++)
    }
  }
}

@Entry
@Component
struct ParentComponent {
  @State score: number = 0;

  build() {
    Column() {
      Text(`Total Score: ${this.score}`)
      // @Link 绑定:用 $ 语法传递引用
      CounterComponent({ value: $score })
    }
  }
}

// ===== @Provide / @Consume — 跨层级数据传递 =====
@Entry
@Component
struct GrandParentComponent {
  @Provide theme: string = 'dark';   // 提供数据
  @Provide user: User = { id: '1', name: 'Alice', email: 'a@b.com', role: 'admin' };

  build() {
    Column() {
      Text(`GrandParent theme: ${this.theme}`)
      ParentComponent()
    }
  }
}

@Component
struct ParentComponent {
  // 中间层不需要传递 theme
  build() {
    Column() {
      ChildComponent()
    }
  }
}

@Component
struct ChildComponent {
  @Consume theme: string;   // 消费数据,自动从祖先组件获取
  @Consume user: User;

  build() {
    Column() {
      Text(`Child theme: ${this.theme}`)
      Text(`Child user: ${this.user.name}`)
    }
  }
}

// ===== @Watch — 监听状态变化 =====
@Component
struct WatchDemo {
  @State @Watch('onPriceChange') price: number = 100;
  @State @Watch('onNameChange') name: string = 'Product';

  // 回调方法名,在状态变化时自动触发
  onPriceChange(newValue: number, oldValue: number): void {
    console.log(`Price changed: ${oldValue} → ${newValue}`);
  }

  onNameChange(newValue: string, oldValue: string): void {
    console.log(`Name changed: ${oldValue} → ${newValue}`);
  }

  build() {
    Column() {
      Text(`${this.name}: ¥${this.price}`)
      Button('Change Price')
        .onClick(() => this.price = 200)
    }
  }
}

UI 构建装饰器

// ===== @Builder — 轻量 UI 复用单元 =====
@Component
struct BuilderDemo {
  @State items: string[] = ['Item 1', 'Item 2', 'Item 3'];

  // @Builder 定义可复用的 UI 片段
  @Builder itemCard(title: string, index: number) {
    Row() {
      Text(`${index + 1}. ${title}`)
        .fontSize(16)
        .layoutWeight(1)
      Button('Delete')
        .onClick(() => this.items.splice(index, 1))
    }
    .width('100%')
    .padding(12)
    .backgroundColor('#f5f5f5')
    .borderRadius(8)
    .margin({ bottom: 8 })
  }

  build() {
    Column() {
      ForEach(this.items, (item: string, index: number) => {
        this.itemCard(item, index)  // 调用 @Builder
      })
    }
    .padding(16)
  }
}

// ===== @Extend — 扩展内置组件样式 =====
// @Extend 只能定义在组件外部,全局可用
@Extend(Text)
function highlightText(color: ResourceColor = '#FF0000') {
  .fontColor(color)
  .fontWeight(FontWeight.Bold)
  .fontSize(18)
}

@Extend(Button)
function primaryButton() {
  .backgroundColor('#007DFF')
  .fontColor('#FFFFFF')
  .borderRadius(20)
  .width('80%')
  .height(44)
}

// 使用
@Component
struct ExtendDemo {
  build() {
    Column() {
      Text('Warning').highlightText('#FF9800')   // 使用扩展样式
      Text('Error').highlightText('#F44336')      // 可传参数
      Button('Submit').primaryButton()             // 使用扩展样式
    }
  }
}

// ===== @Styles — 提取通用样式(比 @Extend 更轻量,不绑定特定组件) =====
@Styles function cardStyle() {
  .width('100%')
  .padding(16)
  .backgroundColor('#FFFFFF')
  .borderRadius(12)
  .shadow({ radius: 4, color: '#1a000000', offsetY: 2 })
}

@Styles function flexCenter() {
  .justifyContent(FlexAlign.Center)
  .alignItems(HorizontalAlign.Center)
}

@Component
struct StylesDemo {
  build() {
    Column() {
      // 多个组件复用相同样式
      Column() {
        Text('Card 1')
      }
      .cardStyle()
      .margin({ bottom: 12 })

      Column() {
        Text('Card 2')
      }
      .cardStyle()
    }
    .flexCenter()
    .width('100%')
    .height('100%')
  }
}

空安全

可选链、非空断言与空值合并

// ===== 可选链 ?. — 安全访问可能为 null/undefined 的属性 =====
interface UserProfile {
  name: string;
  address?: {
    city?: string;
    street?: string;
    zipCode?: string;
  };
  company?: {
    name: string;
    department?: {
      manager?: {
        email?: string;
      };
    };
  };
}

const user: UserProfile = { name: 'Alice' };

// 不用可选链 — 需要逐层检查
let city1: string | undefined;
if (user.address !== undefined && user.address !== null) {
  city1 = user.address.city;
}

// 使用可选链 — 一行搞定
const city: string | undefined = user.address?.city;
const managerEmail: string | undefined = user.company?.department?.manager?.email;

// 可选链用于方法调用
interface Service {
  getData?(): string[];
}

const service: Service = {};
const data = service.getData?.() ?? []; // 安全调用 + 空值合并

// 可选链用于数组访问
const arr: (number | undefined)[] = [1, undefined, 3];
const second: number | undefined = arr[1]?.toFixed(2) as number | undefined;

// ===== 非空断言 ! — 告诉编译器"我确定这里不为空" =====
function processValue(value: string | null): string {
  // 如果你能确定 value 不为 null,使用 !
  return value!.toUpperCase(); // 编译通过,但运行时如果 value 为 null 会报错

  // 更安全的做法 — 用类型守卫
  // if (value !== null) return value.toUpperCase();
  // return '';
}

// 实战场景:DOM 元素获取
// const element = document.getElementById('app')!; // 开发者确定元素存在

// ===== 空值合并 ?? — 提供默认值 =====
const port: number = parseInt('') || 3000;   // 3000,|| 对 0 也视为 falsy
const port2: number = parseInt('') ?? 3000;  // 3000,?? 只对 null/undefined 生效
const zero: number = 0 ?? 42;                // 0,0 不是 null/undefined

// 三者组合使用
function getConfigValue(
  config: Record<string, string | undefined>,
  key: string
): string {
  return config[key]?.trim() ?? 'default';
}

空安全最佳实践

// ===== 类型收窄 — 比 ! 更安全 =====
function processUser(user: User | null): string {
  // ❌ 不推荐 — 非空断言可能崩溃
  // return user!.name;

  // ✅ 推荐 — 类型守卫
  if (user === null) {
    return 'Unknown User';
  }
  return user.name; // TypeScript 自动收窄为 User
}

// ===== 可选参数与空值 =====
interface SearchParams {
  keyword?: string;
  category?: string;
  page?: number;
}

function search(params: SearchParams): string[] {
  const keyword = params.keyword ?? '';           // 空值合并提供默认值
  const category = params.category ?? 'all';
  const page = params.page ?? 1;
  console.log(`Searching "${keyword}" in ${category}, page ${page}`);
  return [];
}

// ===== 嵌套空安全处理 =====
interface AppConfig {
  api?: {
    baseURL?: string;
    timeout?: number;
    headers?: Record<string, string>;
  };
}

function getBaseURL(config: AppConfig): string {
  return config.api?.baseURL ?? 'https://default.api.com';
}

function getTimeout(config: AppConfig): number {
  return config.api?.timeout ?? 5000;
}

function getHeaders(config: AppConfig): Record<string, string> {
  return config.api?.headers ?? { 'Content-Type': 'application/json' };
}

异步编程

Promise

// ===== 创建 Promise =====
function fetchUserData(userId: string): Promise<User> {
  return new Promise<User>((resolve, reject) => {
    // 模拟异步操作(实际使用 @ohos.net.http)
    setTimeout(() => {
      if (userId.startsWith('U')) {
        resolve({
          id: userId,
          name: 'Alice',
          email: 'alice@harmonyos.com',
          role: 'admin'
        });
      } else {
        reject(new Error(`Invalid userId: ${userId}`));
      }
    }, 1000);
  });
}

// ===== Promise 链式调用 =====
fetchUserData('U001')
  .then(user => {
    console.log(`Got user: ${user.name}`);
    return fetchOrders(user.id);
  })
  .then(orders => {
    console.log(`Got ${orders.length} orders`);
  })
  .catch(error => {
    console.error(`Error: ${error.message}`);
  })
  .finally(() => {
    console.log('Request completed');
  });

// ===== Promise 组合 =====
// 并行执行
const [users, products, orders] = await Promise.all([
  request<User[]>('/api/users'),
  request<Product[]>('/api/products'),
  request<Order[]>('/api/orders'),
]);

// 竞速 — 取最快返回的
const fastest = await Promise.race([
  request<string>('/api/cdn1/data'),
  request<string>('/api/cdn2/data'),
]);

// 全部完成(无论成功失败)
const results = await Promise.allSettled([
  request<string>('/api/service-a'),
  request<string>('/api/service-b'),
  request<string>('/api/service-c'),
]);

results.forEach((result, index) => {
  if (result.status === 'fulfilled') {
    console.log(`Service ${index}: ${result.value}`);
  } else {
    console.error(`Service ${index} failed: ${result.reason}`);
  }
});

async / await

// ===== 基础 async/await =====
async function loadUserProfile(userId: string): Promise<User> {
  try {
    const user = await fetchUserData(userId);
    const orders = await fetchOrders(userId);
    const settings = await fetchSettings(userId);
    return { ...user, orders, settings } as User;
  } catch (error) {
    console.error(`Failed to load profile: ${error}`);
    throw error;
  }
}

// ===== 并行 async/await =====
async function loadDashboard(): Promise<void> {
  // 不需要顺序依赖的请求应该并行
  const [users, stats, notifications] = await Promise.all([
    request<User[]>('/api/users'),
    request<DashboardStats>('/api/stats'),
    request<Notification[]>('/api/notifications'),
  ]);

  console.log(`Users: ${users.length}`);
  console.log(`Revenue: ${stats.revenue}`);
  console.log(`Unread: ${notifications.length}`);
}

// ===== async 错误处理 =====
async function safeRequest<T>(url: string): Promise<T | null> {
  try {
    const data = await request<T>(url);
    return data;
  } catch (error) {
    if (error instanceof Error) {
      console.error(`Request failed: ${error.message}`);
    }
    return null;
  }
}

// ===== 实战:带重试的异步请求 =====
async function requestWithRetry<T>(
  url: string,
  maxRetries: number = 3,
  delay: number = 1000
): Promise<T> {
  let lastError: Error | null = null;

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await request<T>(url);
    } catch (error) {
      lastError = error as Error;
      console.warn(`Attempt ${attempt} failed: ${lastError.message}`);
      if (attempt < maxRetries) {
        await new Promise<void>(resolve => setTimeout(resolve, delay * attempt));
      }
    }
  }

  throw lastError!;
}

TaskPool — 鸿蒙并发任务池

// TaskPool 是鸿蒙提供的线程池并发 API,适合 CPU 密集型任务
// 将耗时任务放到子线程执行,避免阻塞 UI 主线程

import taskpool from '@ohos.taskpool';

// ===== 定义任务函数(必须是模块级函数,不能是闭包) =====
@Concurrent
function computeFibonacci(n: number): number {
  if (n <= 1) return n;
  let a = 0, b = 1;
  for (let i = 2; i <= n; i++) {
    const temp = a + b;
    a = b;
    b = temp;
  }
  return b;
}

@Concurrent
function processImage(data: number[]): number[] {
  // 模拟图像处理(灰度化)
  return data.map(pixel => {
    const gray = Math.round(pixel * 0.299 + pixel * 0.587 + pixel * 0.114);
    return gray;
  });
}

// ===== 使用 TaskPool 执行任务 =====
async function runTaskPoolDemo(): Promise<void> {
  try {
    // 执行单个任务
    const result = await taskpool.execute(computeFibonacci, 30);
    console.log(`Fibonacci(30) = ${result}`);

    // 执行多个并行任务
    const task1 = taskpool.execute(computeFibonacci, 20);
    const task2 = taskpool.execute(computeFibonacci, 30);
    const task3 = taskpool.execute(computeFibonacci, 40);

    const [r1, r2, r3] = await Promise.all([task1, task2, task3]);
    console.log(`Results: ${r1}, ${r2}, ${r3}`);
  } catch (error) {
    console.error(`TaskPool error: ${error}`);
  }
}

Worker — 鸿蒙多线程

// Worker 适用于长时间运行的后台线程,如持续的数据处理

import worker from '@ohos.worker';

// ===== 主线程:创建 Worker =====
const workerInstance = new worker.ThreadWorker('workers/data-processor.js');

// 接收 Worker 返回的消息
workerInstance.onmessage = (event: MessageEvents) => {
  const result = event.data;
  console.log(`Worker result: ${JSON.stringify(result)}`);
};

// 接收 Worker 错误
workerInstance.onerror = (event: ErrorEvent) => {
  console.error(`Worker error: ${event.message}`);
};

// 向 Worker 发送消息
workerInstance.postMessage({
  type: 'PROCESS',
  data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
});

// 终止 Worker
// workerInstance.terminate();

// ===== Worker 线程:workers/data-processor.js =====
// const workerPort = worker.workerPort;
//
// workerPort.onmessage = (event) => {
//   const { type, data } = event.data;
//   if (type === 'PROCESS') {
//     const result = data.reduce((sum, val) => sum + val * 2, 0);
//     workerPort.postMessage({ type: 'RESULT', result });
//   }
// };

TaskPool vs Worker 选择指南:

维度TaskPoolWorker
线程管理自动管理线程池手动创建管理
生命周期任务执行完自动回收长期存在,需手动终止
通信方式函数参数/返回值消息机制 postMessage
适用场景短时 CPU 密集任务长时后台任务
数量限制系统调度最多 8 个 Worker
使用复杂度

集合类型

// ===== Array — 有序可重复集合 =====
const fruits: string[] = ['Apple', 'Banana', 'Cherry'];
const numbers: number[] = [1, 2, 3, 4, 5];

// 常用方法
fruits.push('Date');              // 末尾添加
fruits.pop();                     // 末尾移除
fruits.unshift('Apricot');        // 开头添加
fruits.shift();                   // 开头移除

// 遍历
fruits.forEach((fruit, index) => {
  console.log(`${index}: ${fruit}`);
});

// 函数式操作
const upperFruits = fruits.map(f => f.toUpperCase());
const longFruits = fruits.filter(f => f.length > 5);
const hasCherry = fruits.some(f => f === 'Cherry');
const allLong = fruits.every(f => f.length > 3);
const found = fruits.find(f => f.startsWith('C'));
const totalLength = fruits.reduce((sum, f) => sum + f.length, 0);

// 排序
const sorted = [...fruits].sort((a, b) => a.localeCompare(b));
const nums = [3, 1, 4, 1, 5, 9, 2, 6];
const asc = [...nums].sort((a, b) => a - b);
const desc = [...nums].sort((a, b) => b - a);

// ===== Set — 无序不重复集合 =====
const uniqueIds = new Set<string>();
uniqueIds.add('id-1');
uniqueIds.add('id-2');
uniqueIds.add('id-1'); // 重复添加无效
console.log(uniqueIds.size); // 2

// 数组去重
const dupNumbers = [1, 2, 2, 3, 3, 3, 4];
const unique = [...new Set(dupNumbers)]; // [1, 2, 3, 4]

// Set 操作
const setA = new Set([1, 2, 3]);
const setB = new Set([2, 3, 4]);

// 交集
const intersection = new Set([...setA].filter(x => setB.has(x))); // {2, 3}

// 并集
const union = new Set([...setA, ...setB]); // {1, 2, 3, 4}

// 差集
const difference = new Set([...setA].filter(x => !setB.has(x))); // {1}

// ===== Map — 键值对集合 =====
const userCache = new Map<string, User>();

// 增删改查
userCache.set('U001', { id: 'U001', name: 'Alice', email: 'a@b.com', role: 'admin' });
userCache.set('U002', { id: 'U002', name: 'Bob', email: 'b@c.com', role: 'user' });

const user = userCache.get('U001');          // 获取
const exists = userCache.has('U001');        // 是否存在
userCache.delete('U002');                    // 删除
userCache.clear();                           // 清空

// 遍历
userCache.forEach((user, key) => {
  console.log(`${key}: ${user.name}`);
});

for (const [key, value] of userCache) {
  console.log(`${key} → ${value.name}`);
}

// Map 与 Object 的选择
// - 需要任意键类型、频繁增删 → Map
// - 需要 JSON 序列化、固定键集 → Object

// ===== Record — 键值映射类型(TypeScript 工具类型) =====
type RouteMap = Record<string, {
  title: string;
  icon: string;
  path: string;
}>;

const routes: RouteMap = {
  home: { title: '首页', icon: 'home', path: '/home' },
  profile: { title: '我的', icon: 'person', path: '/profile' },
  settings: { title: '设置', icon: 'settings', path: '/settings' },
};

// 实战:枚举到标签的映射
const StatusLabels: Record<HttpStatus, string> = {
  [HttpStatus.OK]: '成功',
  [HttpStatus.Created]: '已创建',
  [HttpStatus.BadRequest]: '请求错误',
  [HttpStatus.Unauthorized]: '未授权',
  [HttpStatus.NotFound]: '未找到',
  [HttpStatus.InternalError]: '服务器错误',
};

ArkTS 运行时与性能优化

方舟编译器 AOT

┌─────────────────────────────────────────────────────────────┐
│              ArkTS 编译执行流程                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ArkTS 源码 (.ets)                                          │
│       │                                                     │
│       ▼                                                     │
│  ┌──────────────┐                                           │
│  │  方舟编译器    │  — 静态类型分析                           │
│  │  (Ark Compiler│  — 类型推断与优化                         │
│  │   AOT)       │  — 内联、逃逸分析、死代码消除              │
│  └──────┬───────┘                                           │
│         │                                                   │
│         ▼                                                   │
│  ┌──────────────┐      ┌──────────────┐                    │
│  │  优化字节码    │  →   │  本地机器码    │                    │
│  │  (方舟字节码)  │      │  (AOT 生成)   │                    │
│  └──────┬───────┘      └──────┬───────┘                    │
│         │                      │                            │
│         ▼                      ▼                            │
│  ┌──────────────────────────────────────────────────────┐  │
│  │              Ark Runtime (方舟运行时)                   │  │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────────────────┐  │  │
│  │  │ GC      │  │ 内存管理 │  │ 并发调度             │  │  │
│  │  │ (分代GC) │  │ (池化)  │  │ (TaskPool/Worker)   │  │  │
│  │  └─────────┘  └─────────┘  └─────────────────────┘  │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

性能优化要点

// ===== 1. 避免动态特性 — 确保类型确定 =====

// ❌ 性能差 — 运行时类型不确定
// let data: any = getResponse();
// let value = data['key'];

// ✅ 性能好 — 编译期类型确定
interface ResponseData {
  key: string;
  value: number;
}
let data: ResponseData = getResponse();
let value: string = data.key;

// ===== 2. 减少对象创建 — 复用对象 =====
@Component
struct OptimizedList {
  @State items: ListItemData[] = [];

  // ❌ 每次 build 创建新对象
  // build() {
  //   List() {
  //     ForEach(this.items, (item) => {
  //       ListItem() {
  //         Row() { Text(item.title) }
  //         .width('100%')
  //         .height(60)
  //         .backgroundColor('#ffffff')
  //       }
  //     })
  //   }
  // }

  // ✅ 使用 @Builder 和 @Styles 复用
  @Builder listItemBuilder(item: ListItemData) {
    ListItem() {
      Row() {
        Text(item.title)
      }
      .width('100%')
      .height(60)
      .cardStyle()  // 复用 @Styles
    }
  }

  build() {
    List() {
      ForEach(this.items, (item: ListItemData) => {
        this.listItemBuilder(item)
      })
    }
  }
}

// ===== 3. 合理使用 @State — 避免不必要的 UI 刷新 =====
@Component
struct StateOptimization {
  // ❌ 整个对象变化会触发全部刷新
  // @State config: AppConfig = { ... };

  // ✅ 拆分细粒度状态
  @State theme: string = 'light';
  @State fontSize: number = 14;
  @State lang: string = 'zh-CN';

  build() {
    // 只有用到 theme 的部分会在 theme 变化时刷新
    Column() {
      Text('Content').fontColor(this.theme === 'dark' ? '#fff' : '#000')
    }
  }
}

// ===== 4. 使用 TaskPool 处理耗时操作 =====
// 参见上文 TaskPool 部分 — 避免阻塞 UI 线程

// ===== 5. 懒加载 — LazyForEach =====
@Component
struct LazyListDemo {
  // LazyForEach 配合 IDataSource 实现按需加载
  private data: MyDataSource = new MyDataSource();

  build() {
    List() {
      // LazyForEach:只渲染可见区域的列表项
      LazyForEach(this.data, (item: ListItemData) => {
        ListItem() {
          Text(item.title).height(60)
        }
      })
    }
    .cachedCount(5) // 缓存额外 5 项,减少滚动时的白块
  }
}

前端开发者学 ArkTS 的注意事项

从 TypeScript 到 ArkTS 的迁移清单

┌─────────────────────────────────────────────────────────────────┐
│              TypeScript → ArkTS 迁移检查清单                      │
├──────┬──────────────────────────────────────────────────────────┤
│ 序号  │ 检查项                                                   │
├──────┼──────────────────────────────────────────────────────────┤
│  1   │ 消除所有 any 类型,替换为具体类型或 unknown                │
│  2   │ 移除所有 eval() 和 with 语句                              │
│  3   │ 为所有函数参数和返回值添加类型注解                          │
│  4   │ 移除 as any 断言,改用 as 具体类型                         │
│  5   │ 确保不修改内置原型(Object.prototype 等)                   │
│  6   │ 动态属性访问改为静态访问或 Record 类型                      │
│  7   │ delete 操作替换为赋值 undefined 或重新构造对象             │
│  8   │ 索引签名 [key: string]: any 改为 Record<string, Type>     │
│  9   │ 模块系统统一使用 ES Modules(import/export)               │
│ 10   │ 了解并使用 ArkUI 装饰器体系替代命令式 UI                   │
└──────┴──────────────────────────────────────────────────────────┘

思维方式转变

前端思维ArkTS 思维说明
命令式 DOM 操作声明式 UI + 状态驱动不要手动操作 UI,修改 @State 即可
npm 生态ohpm 生态包管理器从 npm 切换到 ohpm
React/Vue 组件struct + @Component组件定义方式不同
CSS 样式链式调用属性方法.fontSize(16).color('#333')
Webpack/ViteHvigor构建工具切换
浏览器运行时Ark Runtime运行环境完全不同
DOM 事件ArkUI 事件回调.onClick(() => {})
React Hooks@State/@Prop/@Link状态管理机制不同
Redux/PiniaAppStorage/@Provide全局状态管理不同
// ===== React → ArkTS 对照 =====

// React 写法
// function Counter() {
//   const [count, setCount] = useState(0);
//   return (
//     <View>
//       <Text>{count}</Text>
//       <Button onClick={() => setCount(c => c + 1)}>+1</Button>
//     </View>
//   );
// }

// ArkTS 写法
@Component
struct Counter {
  @State count: number = 0;  // 类似 useState

  build() {
    Column() {
      Text(`${this.count}`)
      Button('+1')
        .onClick(() => this.count++)  // 直接修改 @State
    }
  }
}

// ===== Vue → ArkTS 对照 =====

// Vue 写法
// <template>
//   <div>{{ message }}</div>
//   <button @click="reverse">Reverse</button>
// </template>
// <script setup>
// const message = ref('Hello');
// const reverse = () => message.value = message.value.split('').reverse().join('');
// </script>

// ArkTS 写法
@Component
struct MessageReverser {
  @State message: string = 'Hello';  // 类似 ref

  build() {
    Column() {
      Text(this.message)
      Button('Reverse')
        .onClick(() => {
          this.message = this.message.split('').reverse().join('');
        })
    }
  }
}

常见问题与踩坑

问题原因解决方案
any 类型报错ArkTS 禁止 any使用具体类型或 unknown + 类型守卫
eval 不可用ArkTS 禁止动态代码执行改用函数封装、策略模式
@State 对象属性不更新嵌套对象修改未触发检测使用 @Observed + @ObjectLink
@Prop 无法修改单向数据流设计需要双向绑定改用 @Link
父子传值太深层层 Props 传递繁琐使用 @Provide / @Consume
UI 卡顿主线程执行耗时操作使用 TaskPool / Worker
列表性能差ForEach 一次性渲染全部改用 LazyForEach 按需加载
模块循环依赖互相 import 导致初始化异常抽取公共模块,单向依赖
函数参数缺类型注解ArkTS 要求显式注解为所有参数添加类型
delete 操作受限删除属性影响对象形状设为 undefined 或重建对象

最佳实践

  • 严格遵循 ArkTS 类型约束,不使用 anyevalwith 等动态特性
  • 状态管理选择合适的装饰器:内部状态用 @State,父子通信用 @Prop/@Link,跨层级用 @Provide/@Consume
  • 耗时操作(网络请求、计算、I/O)使用 TaskPool 或 Worker,不阻塞 UI 线程
  • 长列表使用 LazyForEach 代替 ForEach,配合 cachedCount 优化滚动体验
  • 使用 @Builder@Styles 提取复用 UI 片段,减少重复代码
  • 泛型优先于 any 或类型断言,在编译期保证类型安全
  • 空安全优先使用可选链 ?. 和空值合并 ??,减少非空断言 ! 的使用
  • 模块划分清晰,避免循环依赖,静态导入优先于动态导入
  • 枚举使用字符串枚举增强可读性,简单场景可用联合字面量替代
  • 合理使用 readonly 和接口约束,构建不可变数据流

面试题

Q1: ArkTS 和 TypeScript 有什么区别?为什么要限制动态特性?

ArkTS 是基于 TypeScript 扩展的语言,核心区别:1) 禁止 any 类型,强制类型注解;2) 禁止 eval/with 等动态特性;3) 限制动态属性访问和原型链修改;4) 使用 AOT 编译而非 JIT。限制动态特性的原因:方舟编译器(Ark Compiler)在编译期需要确定所有类型信息才能进行优化(内联、逃逸分析、死代码消除),动态特性使得编译器无法做静态分析,导致无法生成高效的本地机器码。AOT 编译的优势是运行时性能接近原生,代价是牺牲灵活性。

Q2: @State、@Prop、@Link、@Provide/@Consume 各自的使用场景是什么?

@State:组件内部状态,变化触发当前组件 UI 刷新,是最基础的状态装饰器;@Prop:父→子单向数据传递,子组件只读,适合展示型子组件;@Link:父子双向绑定,子组件可修改并同步回父组件,使用 $ 语法传递引用(如 value: $count);@Provide/@Consume:跨层级数据传递(类似 React Context),祖先组件 @Provide 提供数据,后代组件 @Consume 消费数据,中间层无需透传。选择原则:内部状态用 @State,父子单向用 @Prop,父子双向用 @Link,跨层级用 @Provide/@Consume。

Q3: ArkTS 的空安全机制有哪些?分别适用于什么场景?

三大机制:1) 可选链 ?.:安全访问可能为 null/undefined 的属性/方法,遇到空值短路返回 undefined,适用于深层嵌套属性的访问(如 user.address?.city);2) 非空断言 !:告诉编译器”我确定不为空”,编译通过但运行时如果为空会崩溃,适用于开发者能确保非空的场景,应谨慎使用;3) 空值合并 ??:当左侧为 null/undefined 时返回右侧默认值,与 || 的区别是 ?? 只对 null/undefined 生效,0、”、false 等 falsy 值不会触发。最佳实践:优先使用可选链和空值合并,减少非空断言。

Q4: TaskPool 和 Worker 有什么区别?如何选择?

TaskPool 是鸿蒙提供的线程池 API,自动管理线程生命周期,通过 @Concurrent 装饰函数后用 taskpool.execute() 提交任务,适合短时 CPU 密集型任务(如数据处理、图片压缩),任务完成后线程自动回收;Worker 是手动创建管理的后台线程,通过 postMessage 通信,适合长时间运行的后台任务(如 WebSocket 长连接、持续数据处理),需要手动 terminate() 终止。选择原则:短时任务用 TaskPool(简单高效),长时任务用 Worker(持续运行),注意 Worker 最多创建 8 个。

Q5: ArkTS 中的泛型约束有哪些方式?请举例说明。

三种主要方式:1) extends 接口约束:<T extends HasLength> 确保 T 有 length 属性,函数内可安全访问 item.length;2) keyof 约束:<K extends keyof T> 确保 K 是 T 的合法属性名,常用于安全属性访问函数 getProperty(obj, key);3) 多重约束(交叉类型):<T extends Identifiable & Timestamped> 要求 T 同时满足多个接口。此外还有 new() 约束(工厂模式:ctor: new () => T)和字面量约束(<T extends string> 限定字符串子类型)。泛型约束的核心目的是在编译期保证类型安全,避免运行时错误。

Q6: @Builder、@Extend、@Styles 三种复用方式有什么区别?

@Builder:定义可复用的 UI 构建逻辑(可含状态逻辑),在组件内部定义,通过 this.builderName() 调用,适合有逻辑的 UI 片段复用(如列表项模板);@Extend:扩展内置组件的样式方法,只能定义在组件外部(全局),绑定特定组件类型,支持传参,如 @Extend(Text) function highlightText(color) 只能用于 Text 组件;@Styles:提取通用样式集合,不绑定特定组件,所有组件都可使用,不能传参(参数需固定),适合纯粹的无逻辑样式复用。选择:纯样式无参数 → @Styles,样式绑定组件类型 → @Extend,含 UI 逻辑 → @Builder。

Q7: ArkTS 中如何实现可辨识联合(Discriminated Union)?它解决了什么问题?

可辨识联合是利用一个共同的字面量属性(辨识属性)来区分联合类型中不同成员的模式。实现步骤:1) 定义多个接口,每个接口含一个相同名称但不同字面量值的属性(如 kind: 'circle');2) 用联合类型组合这些接口;3) 在 switch/if 中根据辨识属性收窄类型。它解决的问题:普通联合类型在收窄时需要用 ininstanceof 判断,不够直观且容易遗漏;可辨识联合让 TypeScript 自动根据辨识属性值收窄到对应接口,保证类型安全。结合 assertNever 可实现穷尽检查,遗漏分支时编译报错。

Q8: 前端开发者从 TypeScript 转到 ArkTS 最大的挑战是什么?如何应对?

最大挑战有三个:1) 动态特性限制 — 不能用 anyeval、动态属性等,需改用静态类型和类型守卫;2) 声明式 UI 范式转变 — 从 React/Vue 的模板或 JSX 切换到 struct + 装饰器的声明式写法,状态管理从 Hooks/Composition API 切换到 @State/@Prop/@Link 装饰器;3) 生态差异 — 从 npm/Webpack 切换到 ohpm/Hvigor,API 从浏览器 API 切换到鸿蒙 SDK。应对策略:先理解 ArkTS 对 TS 的限制(对照迁移清单逐项修改),再学习装饰器驱动的 ArkUI(从简单组件开始),最后熟悉鸿蒙 SDK 和 ohpm 生态。建议先写一个完整的 Todo 应用练手,覆盖状态管理、列表渲染、网络请求、页面导航等核心场景。


相关链接: