【HarmonyOS开发小实践】ArkTS 从 TypeScript 到方舟语言的演进

写 HarmonyOS 应用,绕不开 ArkTS。它是华为给 HarmonyOS 选定的官方高级语言,从 TypeScript 扩展而来,又加了一层静态类型约束和状态管理能力。很多前端同学第一次看到 ArkTS 代码会觉得眼熟,写起来又会发现有些地方跟 TS 不太一样。这篇就把 ArkTS 的定位、它从 TS 演进过来的路径、以及它和 ArkUI 的关系捋清楚。

ArkTS 的定位:HarmonyOS 应用的官方语言

HarmonyOS 应用开发不止一种语言可选,但 ArkTS 是官方主推的那一个。它的定位很明确:给 HarmonyOS 应用开发用的官方高级语言。

这个定位意味着两件事:

第一,ArkTS 是面向应用开发的语言,不是系统级语言。写驱动、写底层服务不是它的活儿,那是 C/C++ 的地盘。ArkTS 写的是应用层的 UI、业务逻辑、数据交互。

第二,它是"高级语言",带类型系统、带装饰器、带完整的工程化能力。不是脚本语言的定位,而是一套有编译工具链、有运行时、有完整生态的语言。

ArkTS 在 TypeScript 生态基础上做了进一步扩展,保持了 TS 的基本风格,同时通过规范定义强化开发期静态检查和分析,提升代码健壮性,并实现更好的程序执行稳定性和性能。

从 TypeScript 到 ArkTS 的演进路径

要理解 ArkTS,得先看它从 TS 演进过来的脉络。这个演进不是推倒重来,而是在 TS 基础上做加减法。
#mermaid-svg-HkZSsMMNZwor7EH3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HkZSsMMNZwor7EH3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HkZSsMMNZwor7EH3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HkZSsMMNZwor7EH3 .error-icon{fill:#552222;}#mermaid-svg-HkZSsMMNZwor7EH3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HkZSsMMNZwor7EH3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HkZSsMMNZwor7EH3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HkZSsMMNZwor7EH3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HkZSsMMNZwor7EH3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HkZSsMMNZwor7EH3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HkZSsMMNZwor7EH3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HkZSsMMNZwor7EH3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HkZSsMMNZwor7EH3 .marker.cross{stroke:#333333;}#mermaid-svg-HkZSsMMNZwor7EH3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HkZSsMMNZwor7EH3 p{margin:0;}#mermaid-svg-HkZSsMMNZwor7EH3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-HkZSsMMNZwor7EH3 .cluster-label text{fill:#333;}#mermaid-svg-HkZSsMMNZwor7EH3 .cluster-label span{color:#333;}#mermaid-svg-HkZSsMMNZwor7EH3 .cluster-label span p{background-color:transparent;}#mermaid-svg-HkZSsMMNZwor7EH3 .label text,#mermaid-svg-HkZSsMMNZwor7EH3 span{fill:#333;color:#333;}#mermaid-svg-HkZSsMMNZwor7EH3 .node rect,#mermaid-svg-HkZSsMMNZwor7EH3 .node circle,#mermaid-svg-HkZSsMMNZwor7EH3 .node ellipse,#mermaid-svg-HkZSsMMNZwor7EH3 .node polygon,#mermaid-svg-HkZSsMMNZwor7EH3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HkZSsMMNZwor7EH3 .rough-node .label text,#mermaid-svg-HkZSsMMNZwor7EH3 .node .label text,#mermaid-svg-HkZSsMMNZwor7EH3 .image-shape .label,#mermaid-svg-HkZSsMMNZwor7EH3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-HkZSsMMNZwor7EH3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HkZSsMMNZwor7EH3 .rough-node .label,#mermaid-svg-HkZSsMMNZwor7EH3 .node .label,#mermaid-svg-HkZSsMMNZwor7EH3 .image-shape .label,#mermaid-svg-HkZSsMMNZwor7EH3 .icon-shape .label{text-align:center;}#mermaid-svg-HkZSsMMNZwor7EH3 .node.clickable{cursor:pointer;}#mermaid-svg-HkZSsMMNZwor7EH3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-HkZSsMMNZwor7EH3 .arrowheadPath{fill:#333333;}#mermaid-svg-HkZSsMMNZwor7EH3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HkZSsMMNZwor7EH3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HkZSsMMNZwor7EH3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HkZSsMMNZwor7EH3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HkZSsMMNZwor7EH3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HkZSsMMNZwor7EH3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-HkZSsMMNZwor7EH3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HkZSsMMNZwor7EH3 .cluster text{fill:#333;}#mermaid-svg-HkZSsMMNZwor7EH3 .cluster span{color:#333;}#mermaid-svg-HkZSsMMNZwor7EH3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HkZSsMMNZwor7EH3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HkZSsMMNZwor7EH3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-HkZSsMMNZwor7EH3 .icon-shape,#mermaid-svg-HkZSsMMNZwor7EH3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HkZSsMMNZwor7EH3 .icon-shape p,#mermaid-svg-HkZSsMMNZwor7EH3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-HkZSsMMNZwor7EH3 .icon-shape .label rect,#mermaid-svg-HkZSsMMNZwor7EH3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HkZSsMMNZwor7EH3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HkZSsMMNZwor7EH3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HkZSsMMNZwor7EH3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 加入静态类型
强化静态检查

加入状态管理
配合 ArkUI
JavaScript
TypeScript
ArkTS
HarmonyOS 应用

演进的核心思路有三条:

第一条,强化静态类型。 TS 的类型系统是可选的,可以写 any,可以关闭严格检查,可以用 @ts-ignore 跳过类型检查。ArkTS 把这些口子都堵上了。any 不让用,unknown 不让用,@ts-ignore 不让用,严格类型检查不是可配置项而是强制的。这么做是为了让编译器能在编译期就把类型问题查出来,减少运行时开销。

第二条,加入状态管理和 UI 描述能力。 TS 是纯语言,不关心 UI。ArkTS 引入了一套装饰器体系,@State@Prop@Link@Component@Entry 这些,专门用来描述 UI 组件和组件间的状态同步。这是 ArkTS 区别于 TS 最明显的地方。

第三条,增强并发能力。 TS/JS 的并发能力支持有限,主要靠 Promise 和 async/await,真正的多线程并发(Worker)用起来比较重。ArkTS 在这基础上加了 TaskPool 和 Worker 两套并发 API,还提出了 Sendable 概念来支持对象在并发实例间的引用传递,提升并发通信性能。

ArkTS 的核心特性

把 ArkTS 摊开看,核心特性有这么几块:

静态类型与严格检查

ArkTS 强制静态类型,编译期就把类型确定下来。这跟 TS 的"渐进式类型"不一样,TS 的类型是给你看的,编译完就擦除了;ArkTS 的类型会参与到编译优化和运行时性能里。

typescript 复制代码
// ArkTS 中不能写 any
// let value: any = 42;  // 编译报错

// 必须显式标注类型,或者让编译器能推断出来
let value: number = 42;
let name: string = 'ArkTS';

// 对象字面量要标注类型
class UserInfo {
  public name: string = '';
  public age: number = 0;
}

let user: UserInfo = { name: '张三', age: 28 };

状态管理装饰器

这是 ArkTS 最有特色的部分。一套装饰器描述 UI 组件的状态和关系:

typescript 复制代码
@Entry
@Component
struct Counter {
  @State count: number = 0;  // 状态变量,变化会触发 UI 刷新

  build() {
    Column() {
      Text(`点击次数: ${this.count}`)
        .fontSize(20)

      Button('加一')
        .onClick(() => {
          this.count++;
        })
    }
  }
}

@State 标记的变量一变,依赖它的 UI 自动刷新。@Prop 做单向同步,@Link 做双向同步。这套机制让 UI 和状态绑定在一起,不用手动调 refresh。

并发能力增强

ArkTS 提供了 TaskPool 和 Worker 两种并发 API,还引入了 Sendable 概念:

typescript 复制代码
import { taskpool } from '@kit.ArkTS';

@Concurrent
function heavyCompute(data: number[]): number {
  // 在子线程跑的耗时计算
  return data.reduce((sum, n) => sum + n, 0);
}

// 主线程调用
let task = new taskpool.Task(heavyCompute, [1, 2, 3, 4, 5]);
taskpool.execute(task).then((result: Object) => {
  console.info(`计算结果: ${result}`);
});

基础类库增强

ArkTS 的基础类库和容器类库比标准 TS 更丰富,提供了高精度数学库 Decimal、Buffer 与 FastBuffer、XML 处理、多种容器库等能力。这些是写应用时常用的工具,官方给你备好了。

与 ArkUI 的关系

ArkTS 和 ArkUI 经常一起出现,容易搞混两者的关系。简单说:ArkTS 是语言,ArkUI 是框架

ArkUI 是 HarmonyOS 的 UI 开发框架,提供了一套声明式的 UI 描述语法。这套语法的载体就是 ArkTS。你在 ArkTS 代码里写的 build() 方法、Column()Text()Button() 这些,就是 ArkUI 提供的组件和 API。

typescript 复制代码
// 这段代码里,ArkTS 提供语言能力,ArkUI 提供 UI 组件
@Entry
@Component
struct MyPage {
  @State message: string = 'Hello';

  build() {  // ArkUI 的组件构建方法
    Column() {  // ArkUI 的布局组件
      Text(this.message)  // ArkUI 的文本组件
        .fontSize(16)
    }
  }
}

两者的分工是:ArkTS 负责类型系统、状态管理装饰器、语言语义;ArkUI 负责组件体系、布局算法、渲染管线。状态管理装饰器(@State 等)是 ArkTS 语言层面的能力,但服务的对象是 ArkUI 的 UI 刷新机制。

与 TS/JS 的互操作

ArkTS 支持与 TS/JS 高效互操作。这意味着你可以复用已有的 TS/JS 代码库,不用全部重写。互操作的场景包括:

  • 在 ArkTS 项目里引用 TS/JS 模块
  • ArkTS 代码调用 TS/JS 导出的函数
  • TS/JS 代码调用 ArkTS 导出的 API

不过互操作有边界。跨语言调用会有一定开销,性能敏感的路径不建议频繁跨语言。另外 ArkTS 的静态类型约束在互操作时仍然生效,从 TS/JS 那边拿到的数据要符合 ArkTS 的类型要求。

编译运行:从源码到执行

ArkTS 代码写完,是怎么跑起来的?这背后是方舟编译运行时(ArkCompiler)在干活。ArkCompiler 分两部分:
#mermaid-svg-REpOnYlYIt29nahZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-REpOnYlYIt29nahZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-REpOnYlYIt29nahZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-REpOnYlYIt29nahZ .error-icon{fill:#552222;}#mermaid-svg-REpOnYlYIt29nahZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-REpOnYlYIt29nahZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-REpOnYlYIt29nahZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-REpOnYlYIt29nahZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-REpOnYlYIt29nahZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-REpOnYlYIt29nahZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-REpOnYlYIt29nahZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-REpOnYlYIt29nahZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-REpOnYlYIt29nahZ .marker.cross{stroke:#333333;}#mermaid-svg-REpOnYlYIt29nahZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-REpOnYlYIt29nahZ p{margin:0;}#mermaid-svg-REpOnYlYIt29nahZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-REpOnYlYIt29nahZ .cluster-label text{fill:#333;}#mermaid-svg-REpOnYlYIt29nahZ .cluster-label span{color:#333;}#mermaid-svg-REpOnYlYIt29nahZ .cluster-label span p{background-color:transparent;}#mermaid-svg-REpOnYlYIt29nahZ .label text,#mermaid-svg-REpOnYlYIt29nahZ span{fill:#333;color:#333;}#mermaid-svg-REpOnYlYIt29nahZ .node rect,#mermaid-svg-REpOnYlYIt29nahZ .node circle,#mermaid-svg-REpOnYlYIt29nahZ .node ellipse,#mermaid-svg-REpOnYlYIt29nahZ .node polygon,#mermaid-svg-REpOnYlYIt29nahZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-REpOnYlYIt29nahZ .rough-node .label text,#mermaid-svg-REpOnYlYIt29nahZ .node .label text,#mermaid-svg-REpOnYlYIt29nahZ .image-shape .label,#mermaid-svg-REpOnYlYIt29nahZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-REpOnYlYIt29nahZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-REpOnYlYIt29nahZ .rough-node .label,#mermaid-svg-REpOnYlYIt29nahZ .node .label,#mermaid-svg-REpOnYlYIt29nahZ .image-shape .label,#mermaid-svg-REpOnYlYIt29nahZ .icon-shape .label{text-align:center;}#mermaid-svg-REpOnYlYIt29nahZ .node.clickable{cursor:pointer;}#mermaid-svg-REpOnYlYIt29nahZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-REpOnYlYIt29nahZ .arrowheadPath{fill:#333333;}#mermaid-svg-REpOnYlYIt29nahZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-REpOnYlYIt29nahZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-REpOnYlYIt29nahZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-REpOnYlYIt29nahZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-REpOnYlYIt29nahZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-REpOnYlYIt29nahZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-REpOnYlYIt29nahZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-REpOnYlYIt29nahZ .cluster text{fill:#333;}#mermaid-svg-REpOnYlYIt29nahZ .cluster span{color:#333;}#mermaid-svg-REpOnYlYIt29nahZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-REpOnYlYIt29nahZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-REpOnYlYIt29nahZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-REpOnYlYIt29nahZ .icon-shape,#mermaid-svg-REpOnYlYIt29nahZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-REpOnYlYIt29nahZ .icon-shape p,#mermaid-svg-REpOnYlYIt29nahZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-REpOnYlYIt29nahZ .icon-shape .label rect,#mermaid-svg-REpOnYlYIt29nahZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-REpOnYlYIt29nahZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-REpOnYlYIt29nahZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-REpOnYlYIt29nahZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ArkCompiler
编译工具链
运行时
ArkTS 源码
方舟字节码 .abc
设备上执行
ArkTS 编译工具链
ArkTS 运行时

ArkTS 编译工具链 负责把高级语言编译成方舟字节码文件(*.abc)。ArkTS 运行时负责在设备侧运行字节码文件,执行程序逻辑。运行时里有解释器、AOT 编译器、JIT 编译器等多种执行方式,根据场景选择最优路径。

这块的细节后面有专门的文章展开讲,这里先知道个大概:ArkTS 代码不是直接解释执行的,会先编译成字节码,再由运行时根据热点情况决定解释执行还是编译执行。

一个完整的 ArkTS 组件示例

把前面讲的特性串起来看一个完整的例子。这是一个带状态管理、异步请求、列表渲染的组件:

typescript 复制代码
import { taskpool } from '@kit.ArkTS';

// 数据模型
class TodoItem {
  public id: number = 0;
  public title: string = '';
  public done: boolean = false;
}

// 模拟异步数据加载
@Concurrent
function fetchTodos(): TodoItem[] {
  // 实际场景里这里会是网络请求或数据库查询
  let result: TodoItem[] = [];
  for (let i = 1; i <= 5; i++) {
    let item: TodoItem = { id: i, title: `任务 ${i}`, done: false };
    result.push(item);
  }
  return result;
}

@Entry
@Component
struct TodoListPage {
  @State todos: TodoItem[] = [];
  @State loading: boolean = false;

  aboutToAppear() {
    this.loadTodos();
  }

  async loadTodos() {
    this.loading = true;
    try {
      let task = new taskpool.Task(fetchTodos);
      let result = await taskpool.execute(task) as TodoItem[];
      this.todos = result;
    } catch (e) {
      console.error(`加载失败: ${e}`);
    } finally {
      this.loading = false;
    }
  }

  build() {
    Column() {
      if (this.loading) {
        Text('加载中...')
          .fontSize(16)
      } else {
        ForEach(this.todos, (item: TodoItem) => {
          Row() {
            Text(item.title)
              .fontSize(16)
              .layoutWeight(1)
            Toggle({ type: ToggleType.Checkbox, isOn: item.done })
              .onChange((isOn: boolean) => {
                item.done = isOn;
              })
          }
          .padding(12)
        }, (item: TodoItem) => item.id.toString())
      }
    }
  }
}

这段代码里用到了 ArkTS 的多个特性:类定义和静态类型、@State 状态管理、@Concurrent 标记并发函数、TaskPool 异步执行、async/await 异步语法、ArkUI 的组件和布局。一个文件里把这些串起来,就是典型的 ArkTS 应用代码组织方式。

ArkTS 的演进方向

ArkTS 不是定死不变的。官方文档里提到,未来会结合应用开发和运行的需求持续演进,逐步提供并发能力增强、系统类型增强、分布式开发范式等更多特性。

从现在的形态看,ArkTS 的设计取向很明确:宁可限制一些灵活性,也要换来性能和稳定性。这个取向跟 HarmonyOS 的设备场景有关------HarmonyOS 要跑在从手机到穿戴到车机等各种设备上,性能和稳定性比语言灵活性更重要。理解了这个取向,就能理解 ArkTS 为什么做了那些限制。

小小总结

别把 ArkTS 当 TS 写。 语法像不代表习惯能照搬。ArkTS 的类型约束更严,any 不能用,对象字面量要标类型,解构赋值不支持。从 TS 项目迁过来要先过类型检查这一关。

状态管理装饰器是 ArkTS 的核心。 写 HarmonyOS 应用,@State@Prop@Link 这套机制要吃透。它不是可选的语法糖,而是 ArkUI 刷新 UI 的基础。理解了状态变量的依赖追踪,才能写出性能好的组件。

并发能力按场景选。 简单的 I/O 异步用 Promise/async/await 就够;CPU 密集的短任务用 TaskPool;长时间运行的后台任务用 Worker。别一上来就 Worker,杀鸡用牛刀。

互操作不是免费的。 ArkTS 调 TS/JS 有跨语言开销,热点路径别频繁跨。能纯 ArkTS 实现的逻辑就别混着写。

官方文档要常看。 ArkTS 还在演进,特性在增,限制在调。写代码遇到编译报错先查文档,可能是某个特性被限制了,也可能是新版本有更好的写法。

相关推荐
张星河zen1 小时前
4096卡、8EFLOPS、7.2T NPO:华为昇腾960超节点详解
华为·ai训练·ai推理·超节点·npo·昇腾960·hi-one
云运维笔记3 小时前
华为设备IP地址配置全攻略
运维·网络·计算机网络·华为
威哥爱编程4 小时前
HarmonyOS 7 星盾机密风控实战:设备风险因子端侧融合计算,可用不可见
harmonyos·arkts
威哥爱编程4 小时前
HarmonyOS 7 应用快启实战:关键资源预加载进内存,冷启告别白屏
华为·harmonyos·arkts
马剑威(威哥爱编程)5 小时前
【共创稿事节】HarmonyOS 7 视觉 AI 进阶实战:人脸检测 + 通用文字识别(OCR)两步接入
华为·harmonyos·arkts
HMS Core17 小时前
HarmonyOS智慧多窗,让应用在任意窗口都“恰到好处”
harmonyos
梦想不只是梦与想17 小时前
鸿蒙 应用发布准备工作(一)
harmonyos·鸿蒙上架·鸿蒙应用发布
马剑威(威哥爱编程)19 小时前
【共创稿事节】HarmonyOS 7 文搜图实战:自然语言检索本地图片,全流程端侧闭环
华为·harmonyos