ArkTS 不是 TypeScript:我踩过的 6 条编译红线【鸿蒙心迹】

刚开始写 ArkTS 时,我最大的误判是:它长得像 TypeScript,原来的写法应该大多能直接用。

真正把一个 Android 项目迁进来以后,编译器很快把这种想法纠正了。对象字面量、异常、类型兼容、any、UI 语法和组件嵌套,都有更明确的限制。

下面 6 类错误都来自实际项目。比起背规则,更有用的是记住每条错误应该先检查哪里。

在这里插入图片描述

一、对象字面量必须有明确类型

报错关键字:

Object literal must correspond to some explicitly declared class or interface
arkts-no-untyped-obj-literals

普通 TypeScript 里,经常直接写:

request({
  path: '/user/info',
  method: ApiHttpMethod.GET
});

迁移到 ArkTS 后,这个匿名对象如果没有明确对应的类或接口,就可能被编译器拦住。我们的处理方式是先定义请求参数类:

export class ApiRequestOptions {
  path: string = '';
  method?: ApiHttpMethod;
  data?: string;
}

调用时显式创建对象:

const options = new ApiRequestOptions();
options.path = '/user/info';
options.method = ApiHttpMethod.GET;
return ApiClient.request(options);

排查这类错误时,不要只盯着报错所在的那一行。调用链中间如果又重新拼了一个匿名对象,同样要改。

二、throw 后面应当是 Error

报错关键字:

arkts-limited-throw

问题代码常见于 catch

catch (error) {
  throw error;
}

这里捕获值的类型并不明确,直接抛出会触发限制。项目里先把错误转成文字,再重新构造 Error

catch (error) {
  const message = ApiClient.errorToMessage(error);
  throw new Error(message);
}

这样做还有一个实际收益:日志和页面提示可以使用同一套错误文本,不必分别猜测异常对象的结构。

三、结构一样,不代表类型兼容

报错关键字:

10605030 ArkTS Compiler Error
Structural typing is not supported
arkts-no-structural-typing

TypeScript 常用“结构相同即可赋值”的方式处理对象。ArkTS 更强调声明出来的类型身份。两个类即使字段完全一样,也不能默认互换。

这类错误在接第三方 SDK 时尤其常见。最稳妥的办法不是自己照着字段重写一个类型,而是直接使用 SDK 导出的类型;需要适配时,显式创建目标类型并逐项赋值。

看到结构类型报错,先检查方法签名是不是凭经验写的,再对照 SDK 的类型声明。

四、别用 any 和 unknown 暂时糊住问题

报错关键字:

10605008 ArkTS Compiler Error
Use explicit types instead of "any", "unknown"
arkts-no-any-unknown

前端项目里遇到复杂返回值,临时写一个 any 很方便。ArkTS 不鼓励这种做法。

我们的处理原则按数据来源区分:

  • 接口返回:建立明确的响应模型;
  • JSON 字符串:解析后尽快转换为业务模型;
  • 第三方回调:使用 SDK 自带类型;
  • 键值参数:在键和值都确定时使用 MapRecord

不要把所有数据都塞进一个“万能对象”。类型越晚补,错误越容易扩散到页面层。

五、build() 里只能放 UI 构建语法

报错原文:

10905209 ArkTS Compiler Error
Only UI component syntax can be written here.

最常见的情况是在组件树里临时写变量、循环或普通逻辑。解决办法是把计算挪到方法、生命周期或事件处理中,重复的 UI 片段则抽成 @Builder

错误思路是“怎样让这段普通代码继续留在 build() 里”,正确问题应当是“它属于状态计算、事件处理,还是 UI 结构”。归类以后,位置自然就清楚了。

六、组件位置和枚举名称不能靠猜

项目里遇到过两条很典型的错误:

The 'Blank' component can only be nested in the 'Row,Column,Flex' parent component.

以及:

Property 'BottomCenter' does not exist on type 'typeof Alignment'.

前一条说明组件有明确的父容器要求;后一条则是把别的平台命名习惯带进了 ArkUI,实际应使用 Alignment.Bottom

这类错误通常不需要设计复杂修复。先看组件文档和枚举声明,把组件放回允许的容器,使用真实存在的枚举值即可。

一张排查表

报错关键字第一检查点
arkts-no-untyped-obj-literals是否直接传了没有明确类型的对象字面量
arkts-limited-throwthrow 后面是不是 Error
arkts-no-structural-typing是否自行仿写了 SDK 类型
arkts-no-any-unknown能否建立接口模型或使用 SDK 声明类型
Only UI component syntax普通逻辑是否混进 build()
can only be nested in组件的父容器是否符合要求
does not exist on type属性或枚举名称是否来自别的平台习惯

这些限制刚接触时会拖慢编码速度,但它们也迫使工程尽早把数据类型、UI 结构和异常边界说清楚。比起在运行时追一个结构不明的对象,编译阶段多改几行通常更便宜。

你遇到最多的是哪一条 ArkTS 规则?如果有完整报错号,排查速度通常会快很多。


系列上一篇:《不会鸿蒙的人,三个月把 Android 项目搬上了鸿蒙【鸿蒙心迹】》

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐