HarmonyOS 应用开发:ArkTS 语言基础与语法详解
ArkTS 是华为鸿蒙生态的主力开发语言,基于 TypeScript 扩展并增强类型安全。内容涵盖核心特性,包括对象字面量必须标注类型及不支持结构化类型。涉及基本数据类型如 number、boolean、string,以及高级数据类型如枚举、联合类型和数组。详细讲解赋值、比较、位运算、逻辑和算术运算符,以及条件、循环、异常处理和 switch 语句等控制流结构,并提供完整代码示例。

ArkTS 是华为鸿蒙生态的主力开发语言,基于 TypeScript 扩展并增强类型安全。内容涵盖核心特性,包括对象字面量必须标注类型及不支持结构化类型。涉及基本数据类型如 number、boolean、string,以及高级数据类型如枚举、联合类型和数组。详细讲解赋值、比较、位运算、逻辑和算术运算符,以及条件、循环、异常处理和 switch 语句等控制流结构,并提供完整代码示例。

参考文档:ArkTS 语言介绍
ArkTS 是华为为鸿蒙生态(HarmonyOS)打造的主力应用开发语言,它在 TypeScript 的基础上进行了深度扩展和约束,以更好地适配声明式 UI 编程模型(如 ArkUI)并提升运行时性能与类型安全性。因此,ArkTS 并非完全兼容 TypeScript,而是'TypeScript 的超集 + 静态强类型增强 + 运行时优化限制'。
下面通过两个典型特性,展示 ArkTS 与标准 TypeScript 的关键差异。
在 TypeScript 中,对象字面量的类型通常可以通过类型推导自动确定,开发者无需显式声明。但在 ArkTS 中,出于编译期类型安全和运行时性能优化的考虑,所有对象字面量都必须显式标注其类型。
我们来看一段相同代码在两种环境下的表现:
const stu = { name: 'zhangsan', age: 19 }
在 ArkTS 中,编译器会报错,提示'对象字面量必须具有显式类型注解':

而在标准 TypeScript 环境中,这段代码完全合法,不会产生任何错误:

因此,在 ArkTS 中,正确的写法应为:
interface Student {
name: string;
age: number;
}
const stu: Student = { name: 'zhangsan', age: 19 };
或直接内联类型注解:
const stu: { name: string; age: number } = { name: 'zhangsan', age: 19 };
这种方式虽然略显冗余,但能确保编译器在早期捕获潜在的类型错误,并为后续的 AOT(Ahead-of-Time)编译提供更精确的类型信息。

TypeScript 采用的是 structural typing(结构化类型),也称为'鸭子类型'——只要两个类型的结构兼容(即拥有相同的属性和方法),就可以互相赋值,即使它们没有继承关系或显式声明。
而 ArkTS 不支持 structural typing,它要求类型匹配必须是名义上的(nominal)或显式兼容的。这意味着,即使一个对象包含了接口所需的所有字段,只要其类型未被明确声明为该接口或其子类型,ArkTS 就会拒绝接受。
示例代码如下:
interface Ani {
name: string;
age: number;
}
function getName(obj: Ani) {
return obj.name;
}
const ani = { name: 'zhangsan', age: 18, gender: '男' };
getName(ani);
在 TypeScript 中,ani 虽然多了一个 gender 属性,但由于它包含 Ani 接口所需的全部字段,因此可以顺利通过类型检查:

但在 ArkTS 中,这段代码会报错,提示类型不匹配:

解决方法是:要么将 ani 显式声明为 Ani 类型(此时不能包含额外属性),要么扩展接口以包含所有实际字段:
interface Ani {
name: string;
age: number;
gender: string; // 显式声明所有字段
}
注:为了避免变量名与接口名冲突,示例中已将接口重命名为
Ani(首字母大写)。
这种设计虽然牺牲了一定的灵活性,但换来了更强的类型安全性和更高效的运行时性能,尤其适合资源受限的嵌入式设备和高性能 UI 渲染场景。

ArkTS 支持多种基础数据类型,这些类型与 JavaScript/TypeScript 基本一致,但在使用上可能有更严格的约束。
ArkTS 中的 number 类型用于表示整数和浮点数,底层统一使用 64 位双精度浮点数(IEEE 754 标准)。支持十进制、科学计数法、小数等多种字面量形式。

boolean 类型仅有两个取值:true 和 false,主要用于控制程序流程,如条件判断、循环控制等。ArkTS 不允许将非布尔值(如数字、字符串)隐式转换为布尔值,必须显式判断。

string 类型用于表示文本数据。ArkTS 支持三种字符串字面量:
'...'"..."`...`(模板字符串,支持 ${表达式} 插值)字符串中的特殊字符(如换行 、制表符 )需使用转义序列表示。

以下是一个完整的 UI 示例,展示了如何在 ArkTS 组件中使用这些基本类型:
@Entry
@Component
struct Index {
build() {
Column() {
Button('数字类型').onClick(() => {
let n1 = 3.14;
let n2 = 3.141592;
let n3 = 0.5;
let n4 = 1e2; // 科学计数法:100
console.log('数字类型', n1);
console.log('数字类型', n2);
console.log('数字类型', n3);
console.log('数字类型', n4);
})
Button('布尔类型').onClick(() => {
let isFDone: boolean = false;
let isTDone: boolean = true;
console.log('布尔类型', isFDone);
console.log('布尔类型', isTDone);
})
Button('字符串类型').onClick(() => {
let s1 = 'Hello, world!\n'; // 包含换行符
let s2 = 'this is a string';
let a = 'Success';
let s3 = `The result is ${a}`; // 模板字符串插值
console.log('字符串类型', s1);
console.log('字符串类型', s2);
console.log('字符串类型', a);
console.log('字符串类型', s3);
})
}
}
}
除了基本类型,ArkTS 还提供了多种复合类型,用于构建更复杂的数据结构。
枚举(enum)是一种定义命名常量集合的方式,有助于提高代码可读性和维护性。ArkTS 支持字符串枚举和数值枚举,推荐使用字符串枚举,因其更具语义且不易受顺序变更影响。
使用时必须通过 EnumName.Value 的形式访问,不能直接使用字符串字面量替代(除非显式比较)。

联合类型使用 | 符号连接多个类型,表示一个变量可以是其中任意一种类型。例如 string | number 表示该变量既可以是字符串,也可以是数字。
这在处理可能返回多种结果的函数(如 API 响应、用户输入)时非常有用。

数组是存储有序元素的集合。ArkTS 支持两种数组声明方式:
let arr: number[] = [1, 2, 3];let arr: Array<string> = ['a', 'b'];数组支持动态扩容(如 arr[100] = 100),但出于性能考虑,建议预先分配合理大小。

ArkTS 支持丰富的运算符,用于执行各种计算和逻辑操作。
基础赋值:x = y
复合赋值(结合算术或位运算):
+=, -= , *= , /= , %=<<=, >>=, >>>=(位移)&=, |=, ^=(位运算)这些运算符在简化代码的同时,也提升了执行效率。

用于比较两个值的大小或相等性,返回布尔结果:
>, <, >=, <===, !=(值相等)===, !==(严格相等,推荐使用)注意:ArkTS 强烈建议使用
===和!==,避免因类型转换导致意外行为。


对整数的二进制位进行操作,常用于权限控制、标志位设置等底层场景:
&(按位与)|(按位或)^(按位异或)~(按位取反)<<(左移)、>>(带符号右移)、>>>(无符号右移)

用于组合多个布尔表达式:
&&(逻辑与):全真才真||(逻辑或):一真即真!(逻辑非):取反支持短路求值(short-circuit evaluation),即在结果确定后不再计算后续表达式。


执行基本数学运算:
+, -, *, /, %(取余)++, --(自增/自减)注意:+ 也可用于字符串拼接,但混合类型操作需谨慎。

ArkTS 支持常见的程序控制语句,用于实现逻辑分支与循环。
根据布尔表达式的值决定是否执行某段代码。可嵌套使用,也可配合三元运算符简化简单判断。

for 循环适用于已知迭代次数的场景,由初始化、条件判断、更新表达式三部分组成。

当循环次数不确定,但满足某个条件时持续执行,适合处理动态数据流或用户交互。

用于异常处理。throw 抛出错误,try...catch 捕获并处理异常,防止程序崩溃。
注意:ArkTS 中的异常处理主要用于调试和边界情况,不建议在常规逻辑中频繁使用。

多分支选择结构,比多个 if-else 更清晰。每个 case 必须以 break 结束,否则会'穿透'到下一个分支。
支持字符串、数字、枚举等类型作为判断条件。

以下为完整示例代码,涵盖上述所有知识点。当前被注释掉的部分可根据需要逐步启用,用于测试不同功能模块。
@Entry
@Component
struct Index {
build() {
Column() {
// 数据类型
/*
Button('数字类型').onClick(() => {
let n1 = 3.14;
let n2 = 3.141592;
let n3 = 0.5;
let n4 = 1e2;
console.log('数字类型', n1);
console.log('数字类型', n2);
console.log('数字类型', n3);
console.log('数字类型', n4);
})
Button('布尔类型').onClick(() => {
let isFDone: boolean = false;
let isTDone: boolean = true;
console.log('布尔类型', isFDone);
console.log('布尔类型', isTDone);
})
Button('字符串类型').onClick(() => {
let s1 = 'Hello, world!\n';
let s2 = 'this is a string';
let a = 'Success';
let s3 = `The result is ${a}`;
console.log('字符串类型', s1);
console.log('字符串类型', s2);
console.log('字符串类型', a);
console.log('字符串类型', s3);
})
Button('枚举类型').onClick(() => {
let grade = Grade.优;
if (grade == 'A') {
console.log('枚举类型:优');
} else {
console.log('枚举类型:错误');
}
})
Button('联合类型').onClick(() => {
let GradeAll: string | number | null = 1;
console.log('联合类型', GradeAll);
GradeAll = null;
console.log('联合类型', GradeAll);
GradeAll = "A";
console.log('联合类型', GradeAll);
})
Button('数组类型').onClick(() => {
// 数组定义
let arr: string[] = ['1', '2', '3', '4'];
let arr2: number[] = new Array(10);
// 下标
console.log('数组类型', arr[3]);
// 支持动态扩容
arr2[100] = 100;
console.log('数组类型', arr2.length);
})
*/
// 运算符
/*
// 赋值运算符
Button('赋值运算符').onClick(() => {
let a: number = 10;
let b: number = 20;
let c: number = 30;
console.log('赋值运算符', a, b, c);
})
// 算数运算符
Button('算数运算符').onClick(() => {
let a = 10;
let b = 20;
console.log('算数运算符:加法', a + b);
console.log('算数运算符:减法', a - b);
console.log('算数运算符:乘法', a * b);
console.log('算数运算符:除法', a / b);
console.log('算数运算符:取余', a % b);
console.log('算数运算符:自增', a++);
console.log('算数运算符:自减', a--);
})
// 比较运算符
Button('比较运算符').onClick(() => {
let a = 10;
let b = 20;
console.log('大于', a > b);
console.log('小于', a < b);
console.log('等于', a == b);
console.log('不等于', a != b);
console.log('大于等于', a >= b);
console.log('小于等于', a <= b);
})
// 逻辑运算符
Button('逻辑运算符').onClick(() => {
let a = 10;
let b = 20;
console.log('逻辑与', a > 5 && b > 10);
console.log('逻辑或', a > 5 || b > 10);
console.log('逻辑非', !(a > 5));
})
// 位运算符
Button('位运算符').onClick(() => {
let a = 10;
let b = 20;
console.log('按位与', a & b);
console.log('按位或', a | b);
console.log('按位异或', a ^ b);
console.log('按位取反', ~a);
console.log('左移', a << 1);
console.log('右移', a >> 1);
})
*/
// 语句
/*
Button('条件语句').onClick(() => {
let grade = Grade.优;
if (grade == 'A') {
console.log('枚举类型:优');
} else {
console.log('枚举类型:错误');
}
})
// 循环
Button('循环语句').onClick(() => {
for (let i = 0; i < 10; i++) {
console.log('循环语句', i);
}
})
// while 循环
Button('while 循环').onClick(() => {
let i = 0;
while (i < 10) {
console.log('while 循环', i);
i++;
}
})
// throw 和 try 语句
Button('throw 和 try 语句').onClick(() => {
try {
throw new Error('throw 和 try 语句');
} catch (e) {
console.log(e.message);
}
})
// switch 语句
Button('switch 语句').onClick(() => {
let grade = 'A';
switch (grade) {
case 'A':
console.log('switch 语句:优');
break;
case 'B':
console.log('switch 语句:良');
break;
case 'C':
console.log('switch 语句:中');
break;
case 'D':
console.log('switch 语句:差');
break;
}
})
*/
}
}
}
enum Grade {
'优' = 'A',
'良' = 'B',
'中' = 'C',
'差' = 'D',
}

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online