HarmonyOS应用开发实战(基础篇)Day01-《ArkTS基本知识》

ArkTS基本知识
- 1、ArkTS语言特点
- 1.1、对象字面量必须标注类型
- 1.2、不支持 Structural Typing(结构化类型)
- 2、ArkTS基本数据类型
- 2.1、number 类型
- 2.2、boolean 类型
- 2.3、string 类型
- 3、高级数据类型
- 3.1、枚举类型(enum)
- 3.2、联合类型(Union Types)
- 3.3、数组类型(Array)
- 4、运算符
- 4.1、赋值运算符
- 4.2、比较运算符
- 4.3、位运算符
- 4.4、逻辑运算符
- 4.5、算术运算符
- 5、语句
- 5.1、条件语句(if / else)
- 5.2、循环语句(for)
- 5.3、while 语句
- 5.4、throw 和 try 语句
- 5.5、switch 语句
- 代码部分
1、ArkTS语言特点
参考文档:ArkTS语言介绍
ArkTS 是华为为鸿蒙生态(HarmonyOS)打造的主力应用开发语言,它在 TypeScript 的基础上进行了深度扩展和约束,以更好地适配声明式 UI 编程模型(如 ArkUI)并提升运行时性能与类型安全性。因此,ArkTS 并非完全兼容 TypeScript,而是“TypeScript 的超集 + 静态强类型增强 + 运行时优化限制”。
下面通过两个典型特性,展示 ArkTS 与标准 TypeScript 的关键差异。
1.1、对象字面量必须标注类型
在 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)编译提供更精确的类型信息。

1.2、不支持 Structural Typing(结构化类型)
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 渲染场景。

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

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

2.3、string 类型
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!
'; // 包含换行符
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);
})
}
}
}
3、高级数据类型
除了基本类型,ArkTS 还提供了多种复合类型,用于构建更复杂的数据结构。
3.1、枚举类型(enum)
枚举(enum)是一种定义命名常量集合的方式,有助于提高代码可读性和维护性。ArkTS 支持字符串枚举和数值枚举,推荐使用字符串枚举,因其更具语义且不易受顺序变更影响。
使用时必须通过 EnumName.Value 的形式访问,不能直接使用字符串字面量替代(除非显式比较)。

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

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

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

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


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


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


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

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

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

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

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

5.5、switch 语句
多分支选择结构,比多个 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!
';
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);
})
// 逻辑运算符
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',
}









