摘要:从 JavaScript 的自由世界迁移到 ArkTS 的严苛法治社会,最大的痛苦莫过于类型系统。ArkTS 不支持
any的滥用,不支持运行时的动态属性添加。本文记录了我们在桥接 Cordova 插件时,如何优雅地定义接口,处理 JSON 解析的类型断言,并解决 “Property does not exist” 编译报错。
🛑 1. 拒绝 Any
在 JS 中,我们习惯了:
function handleData(data) {
console.log(data.code, data.msg); // 直接点
}
在 ArkTS 中,如果 data 是 Object 或 any,编译器会直接报错或警告。ArkTS 强制推行静态类型检查。
📐 2. 接口定义实战
为了适配 Cordova 传来的 JSON 数据,我们需要定义清晰的 Interface。
// 定义 Cordova 消息结构
interface CordovaMessage {
callbackId: string;
service: string;
action: string;
args: Array<string | number | boolean>; // 联合类型
}
// 泛型处理
class Bridge<T> {
sendMessage(msg: T) { ... }
}
🔨 3. 动态对象的痛
JS 最强大的地方在于可以动态给对象加属性:obj.newProp = 1。
ArkTS 禁止这样做。所有的属性必须在类或接口中预先定义。
场景:我们需要构建一个包含动态参数的 Plugin Result。
错误写法:
let result = {};
result.status = 1; // Error: Property 'status' does not exist on type '{}'
正确写法 1:Record 类型
let result: Record<string, Object> = {};
result['status'] = 1;
result['message'] = 'OK';
正确写法 2:类定义
class PluginResult {
status: number = 0;
message: string = '';
keepCallback: boolean = false;
}
let result = new PluginResult();
result.status = 1;
🧩 4. JSON 解析的类型断言
当使用 JSON.parse() 时,返回值是 Object。要使用里面的属性,必须进行类型断言(Type Assertion)或者类型守卫(Type Guard)。
const jsonStr = '{"score": 100}';
const data = JSON.parse(jsonStr) as Record<string, number>; // 危险的断言
// 更安全的做法:类型转换函数
class GameData {
score: number = 0;
}
function parseGameData(json: string): GameData {
// 在 ArkTS 中,plain object 转 class instance 需要谨慎
// 通常建议手动映射,或者使用第三方库(如果支持 ArkTS)
let obj = JSON.parse(json) as Record<string, number>;
let data = new GameData();
data.score = obj['score'] ?? 0;
return data;
}
⚠️ 5. 兼容性陷阱
ArkTS 仅支持 ES Module,不支持 CommonJS (require)。
这意味着很多 npm 上的老旧 JS 库无法直接引入。
解决方案:
- 寻找对应的 ArkTS 版本库(OpenHarmony 三方库中心)。
- 如果必须用 JS 库,将其放入
src/main/resources/rawfile,在 Webview 中运行,而不是在 ArkTS 线程中运行。
📚 6. 总结
虽然 ArkTS 的"类型洁癖"在初期开发时让人抓狂,迫使我们多写了很多 interface 和 class 定义。
但从长远来看,它极大地提升了代码的可维护性和健壮性。
在重构 2048 插件系统的过程中,得益于静态类型检查,我们在编译阶段就发现了 3 个潜在的参数传递错误,避免了线上的 Crash。
拥抱类型,就是拥抱安全。
1338

被折叠的 条评论
为什么被折叠?



