前言很多人第一次看 HarmonyOS 的代码发现它长得挺像 TypeScript又好像多了些奇怪的东西——Component、State、build()方法……这些是啥ArkTS是华为基于 TypeScript 4.x 扩展的编程语言。TypeScript 能写的ArkTS 基本都能写ArkTS 还额外提供了一套用于构建 UI 的扩展语法。本篇我们从项目源码出发把 ArkTS 的基础语法捋一遍让你读懂后续所有代码。项目预览一、ArkTS 的核心基础1.1 变量声明ArkTS 使用let变量和const常量这和 TypeScript / JavaScript 完全一样letcount:number0;// 数字类型constname:stringHello;// 字符串常量letisVisible:booleantrue;// 布尔类型letitems:string[][];// 字符串数组提示ArkTS 要求强制类型标注不能像 JS 那样写let x 1就不管类型了。变量声明时最好明确写出类型养成好习惯。1.2 函数定义// 普通函数functionadd(a:number,b:number):number{returnab;}// 箭头函数constgreet(name:string):string{returnHello,${name};};// async 异步函数项目中大量使用asyncfunctionfetchData():Promisestring{letresultawaitsomeAsyncOperation();returnresult;}项目中的MapUtil.ets里大量使用了async/await比如获取当前位置// entry/src/main/ets/utils/MapUtil.etsasyncgetMyLocation():PromisegeoLocationManager.Location{letlocation:geoLocationManager.LocationawaitgeoLocationManager.getCurrentLocation();returnlocation;}async表示这个方法是异步的await等待异步操作完成返回类型是PromiseLocation。二、interface 和 class2.1 interface 接口接口定义数据的形状规定一个对象应该有哪些字段// entry/src/main/ets/model/StationData.etsexportinterfaceStationData{image:ResourceStr;// 图片资源可以是字符串或资源引用id:string;// 唯一标识name:string;// 加油站名称addr:string;// 地址latitude:number;// 纬度longitude:number;// 经度}这是项目里的加油站数据模型。定义interface之后我们创建的每个加油站数据对象都必须包含这些字段少了会报错。// 正确的使用方式letstation:StationData{image:$r(app.media.image1),id:1,name:中国石化加油站(AA站),addr:N市J区XX大街587号,latitude:31.937176963332842,longitude:118.86018812656404,};2.2 class 类类是对功能的封装。项目中的工具类都用class实现// entry/src/main/ets/utils/Logger.etsexportclassLogger{privatestaticdomain:number0x0000;// 私有静态属性privatestaticprefix:stringNearByGasStationDemo;staticinfo(...args:string[]):void{// 静态方法直接 Logger.info() 调用hilog.info(Logger.domain,Logger.prefix,Logger.format,args);}staticerror(...args:string[]):void{hilog.error(Logger.domain,Logger.prefix,Logger.format,args);}}static的意思不需要实例化就能调用直接Logger.info(消息)用。private的意思只在类内部能访问外部访问不到。// 外部使用方式Logger.info(testTag,初始化成功);Logger.error(testTag,出错了:${err.message});2.3 Observed 装饰的类这是 ArkTS 特有的扩展。给一个类加上Observed表示这个类的实例被 UI 框架观察它的属性变化会触发 UI 刷新// entry/src/main/ets/utils/MapUtil.etsObservedexportclassMapUtil{// ... 方法实现}提示Observed常和ObjectLink装饰器配合使用实现深层数据的响应式更新。本项目中MapUtil使用Observed主要是为了标识这是一个可观察对象为后续状态联动做准备。三、export 和 importArkTS 使用 ES Module 的模块系统跟 TypeScript/JavaScript 完全一样。3.1 导出// 导出 interfaceexportinterfaceStationData{...}// 导出常量exportconstSTATION_LIST:StationData[][...];// 导出 classexportclassLogger{...}// 默认导出一个文件只能有一个exportdefaultclassEntryAbilityextendsUIAbility{...}3.2 导入// 从相对路径导入import{Constants}from../common/Constants;import{Logger}from../utils/Logger;import{STATION_LIST,StationData}from../model/StationData;// 从 Kit 包导入HarmonyOS 系统能力import{map,mapCommon,MapComponent}fromkit.MapKit;import{geoLocationManager}fromkit.LocationKit;import{abilityAccessCtrl,Permissions}fromkit.AbilityKit;kit.MapKit这样的kit.xxx是 HarmonyOS 提供的系统 Kit 包不需要手动安装直接import就能用。四、ArkTS 特有扩展装饰器这是 ArkTS 和普通 TypeScript 差别最大的地方。装饰器以开头用来给类、方法、属性加上标签告诉框架这个东西是干什么用的。4.1 组件相关装饰器装饰器作用Entry标记一个组件为页面入口每个页面有且只有一个Component标记为 ArkUI 组件可复用的 UI 单元Builder标记为构建函数可以在build()里调用的 UI 片段// MainPage.etsEntry// 这是页面入口Component// 这是一个组件struct MainPage{build(){// UI 构建逻辑}}提示注意是struct结构体而不是class。在 ArkTS 中UI 组件必须用struct定义不能用class。4.2 状态管理装饰器装饰器作用State组件内部状态变化时触发 UI 刷新StorageProp从 AppStorage 读取值AppStorage 变化时同步更新Prop从父组件接收数据单向同步Link从父组件接收数据双向同步项目中最常见的用法// GasStationPage.etsComponentstruct GasStationPage{StatestationInfoList:StationData[][];// 内部状态加油站列表Statelatitude:number0;// 内部状态当前纬度StateisShow:booleanfalse;// 内部状态是否显示底部弹窗StorageProp(bottomRectHeight)// 从全局存储读取导航栏高度bottomRectHeight:number0;StorageProp(topRectHeight)// 从全局存储读取状态栏高度topRectHeight:number0;}State是最重要的当State修饰的变量值发生变化时组件会自动重新渲染不需要手动调用任何刷新方法。这是响应式编程的核心。五、可选类型与非空断言5.1 可选类型?在 ArkTS 中?表示这个属性或参数是可选的// 可选属性privatemapOptions?:mapCommon.MapOptions;// 可能是 undefined// 可选参数moveToGasStation(latitude?:number,longitude?:number):void{if(latitudelongitude){// 需要先检查是否有值// ...}}5.2 非空断言!当你确定某个值不是null/undefined但 TypeScript 不知道可以用!告诉编译器相信我它不为空// MapUtil.etsmapUtil.moveToCurrentPosition(this.latitude,this.longitude,this.mapControllerasmap.MapComponentController// 类型断言);as是类型断言相当于我确定它是这个类型。六、展开运算符与数组操作项目中用到了一些 TypeScript 常见的数组操作// forEach 遍历this.stationInfoList.forEach(async(stationItem:StationData){awaitmapUtil.addMapMaker(stationItem.latitude,stationItem.longitude,this.mapControllerasmap.MapComponentController);});forEach接收一个回调函数对数组每个元素执行操作。注意这里的回调是async的意味着每次添加标记都是异步操作。总结这篇文章覆盖了项目中用到的所有 ArkTS 基础语法变量与函数和 TypeScript 基本一致interface定义数据模型的形状class封装工具方法static方法直接调用export/import模块化管理代码装饰器ArkTS 特有Entry、Component、State是最常用的三个可选类型与非空断言处理可能为空的情况下一篇我们开始讲ArkUI 声明式 UI搞清楚Column、Row、Text、Image这些组件是怎么拼在一起构建界面的。
【HarmonyOS实战】 ArkTS语言基础:从TypeScript到鸿蒙的第一步
发布时间:2026/6/5 11:24:51
前言很多人第一次看 HarmonyOS 的代码发现它长得挺像 TypeScript又好像多了些奇怪的东西——Component、State、build()方法……这些是啥ArkTS是华为基于 TypeScript 4.x 扩展的编程语言。TypeScript 能写的ArkTS 基本都能写ArkTS 还额外提供了一套用于构建 UI 的扩展语法。本篇我们从项目源码出发把 ArkTS 的基础语法捋一遍让你读懂后续所有代码。项目预览一、ArkTS 的核心基础1.1 变量声明ArkTS 使用let变量和const常量这和 TypeScript / JavaScript 完全一样letcount:number0;// 数字类型constname:stringHello;// 字符串常量letisVisible:booleantrue;// 布尔类型letitems:string[][];// 字符串数组提示ArkTS 要求强制类型标注不能像 JS 那样写let x 1就不管类型了。变量声明时最好明确写出类型养成好习惯。1.2 函数定义// 普通函数functionadd(a:number,b:number):number{returnab;}// 箭头函数constgreet(name:string):string{returnHello,${name};};// async 异步函数项目中大量使用asyncfunctionfetchData():Promisestring{letresultawaitsomeAsyncOperation();returnresult;}项目中的MapUtil.ets里大量使用了async/await比如获取当前位置// entry/src/main/ets/utils/MapUtil.etsasyncgetMyLocation():PromisegeoLocationManager.Location{letlocation:geoLocationManager.LocationawaitgeoLocationManager.getCurrentLocation();returnlocation;}async表示这个方法是异步的await等待异步操作完成返回类型是PromiseLocation。二、interface 和 class2.1 interface 接口接口定义数据的形状规定一个对象应该有哪些字段// entry/src/main/ets/model/StationData.etsexportinterfaceStationData{image:ResourceStr;// 图片资源可以是字符串或资源引用id:string;// 唯一标识name:string;// 加油站名称addr:string;// 地址latitude:number;// 纬度longitude:number;// 经度}这是项目里的加油站数据模型。定义interface之后我们创建的每个加油站数据对象都必须包含这些字段少了会报错。// 正确的使用方式letstation:StationData{image:$r(app.media.image1),id:1,name:中国石化加油站(AA站),addr:N市J区XX大街587号,latitude:31.937176963332842,longitude:118.86018812656404,};2.2 class 类类是对功能的封装。项目中的工具类都用class实现// entry/src/main/ets/utils/Logger.etsexportclassLogger{privatestaticdomain:number0x0000;// 私有静态属性privatestaticprefix:stringNearByGasStationDemo;staticinfo(...args:string[]):void{// 静态方法直接 Logger.info() 调用hilog.info(Logger.domain,Logger.prefix,Logger.format,args);}staticerror(...args:string[]):void{hilog.error(Logger.domain,Logger.prefix,Logger.format,args);}}static的意思不需要实例化就能调用直接Logger.info(消息)用。private的意思只在类内部能访问外部访问不到。// 外部使用方式Logger.info(testTag,初始化成功);Logger.error(testTag,出错了:${err.message});2.3 Observed 装饰的类这是 ArkTS 特有的扩展。给一个类加上Observed表示这个类的实例被 UI 框架观察它的属性变化会触发 UI 刷新// entry/src/main/ets/utils/MapUtil.etsObservedexportclassMapUtil{// ... 方法实现}提示Observed常和ObjectLink装饰器配合使用实现深层数据的响应式更新。本项目中MapUtil使用Observed主要是为了标识这是一个可观察对象为后续状态联动做准备。三、export 和 importArkTS 使用 ES Module 的模块系统跟 TypeScript/JavaScript 完全一样。3.1 导出// 导出 interfaceexportinterfaceStationData{...}// 导出常量exportconstSTATION_LIST:StationData[][...];// 导出 classexportclassLogger{...}// 默认导出一个文件只能有一个exportdefaultclassEntryAbilityextendsUIAbility{...}3.2 导入// 从相对路径导入import{Constants}from../common/Constants;import{Logger}from../utils/Logger;import{STATION_LIST,StationData}from../model/StationData;// 从 Kit 包导入HarmonyOS 系统能力import{map,mapCommon,MapComponent}fromkit.MapKit;import{geoLocationManager}fromkit.LocationKit;import{abilityAccessCtrl,Permissions}fromkit.AbilityKit;kit.MapKit这样的kit.xxx是 HarmonyOS 提供的系统 Kit 包不需要手动安装直接import就能用。四、ArkTS 特有扩展装饰器这是 ArkTS 和普通 TypeScript 差别最大的地方。装饰器以开头用来给类、方法、属性加上标签告诉框架这个东西是干什么用的。4.1 组件相关装饰器装饰器作用Entry标记一个组件为页面入口每个页面有且只有一个Component标记为 ArkUI 组件可复用的 UI 单元Builder标记为构建函数可以在build()里调用的 UI 片段// MainPage.etsEntry// 这是页面入口Component// 这是一个组件struct MainPage{build(){// UI 构建逻辑}}提示注意是struct结构体而不是class。在 ArkTS 中UI 组件必须用struct定义不能用class。4.2 状态管理装饰器装饰器作用State组件内部状态变化时触发 UI 刷新StorageProp从 AppStorage 读取值AppStorage 变化时同步更新Prop从父组件接收数据单向同步Link从父组件接收数据双向同步项目中最常见的用法// GasStationPage.etsComponentstruct GasStationPage{StatestationInfoList:StationData[][];// 内部状态加油站列表Statelatitude:number0;// 内部状态当前纬度StateisShow:booleanfalse;// 内部状态是否显示底部弹窗StorageProp(bottomRectHeight)// 从全局存储读取导航栏高度bottomRectHeight:number0;StorageProp(topRectHeight)// 从全局存储读取状态栏高度topRectHeight:number0;}State是最重要的当State修饰的变量值发生变化时组件会自动重新渲染不需要手动调用任何刷新方法。这是响应式编程的核心。五、可选类型与非空断言5.1 可选类型?在 ArkTS 中?表示这个属性或参数是可选的// 可选属性privatemapOptions?:mapCommon.MapOptions;// 可能是 undefined// 可选参数moveToGasStation(latitude?:number,longitude?:number):void{if(latitudelongitude){// 需要先检查是否有值// ...}}5.2 非空断言!当你确定某个值不是null/undefined但 TypeScript 不知道可以用!告诉编译器相信我它不为空// MapUtil.etsmapUtil.moveToCurrentPosition(this.latitude,this.longitude,this.mapControllerasmap.MapComponentController// 类型断言);as是类型断言相当于我确定它是这个类型。六、展开运算符与数组操作项目中用到了一些 TypeScript 常见的数组操作// forEach 遍历this.stationInfoList.forEach(async(stationItem:StationData){awaitmapUtil.addMapMaker(stationItem.latitude,stationItem.longitude,this.mapControllerasmap.MapComponentController);});forEach接收一个回调函数对数组每个元素执行操作。注意这里的回调是async的意味着每次添加标记都是异步操作。总结这篇文章覆盖了项目中用到的所有 ArkTS 基础语法变量与函数和 TypeScript 基本一致interface定义数据模型的形状class封装工具方法static方法直接调用export/import模块化管理代码装饰器ArkTS 特有Entry、Component、State是最常用的三个可选类型与非空断言处理可能为空的情况下一篇我们开始讲ArkUI 声明式 UI搞清楚Column、Row、Text、Image这些组件是怎么拼在一起构建界面的。