为什么需要进阶 ArkTS
入门 ArkTS 能写页面,但项目一大,重复代码、脆弱的类型、难以复用的组件就会拖慢节奏。进阶的关键是把类型系统用起来:泛型消灭重复,装饰器复用能力,接口约束边界。
类型就是最好的文档,编译器就是你最严格的评审。
ArkTS 以 TypeScript 为基础做了严格化裁剪:没有 any 的随意逃逸,对象字面量要求明确类型,这在团队协作里反而是优势——代码跑起来之前,错误先被拦住一大半。
泛型:让类型动起来
泛型把「类型」变成参数。同一个函数,既能处理数组也能处理列表,类型却不会丢。ArkTS 的泛型语法和 TypeScript 一致,约束用 extends 表达。
function firstOf<T>(items: T[]): T | undefined {
return items.length > 0 ? items[0] : undefined
}
interface HasId {
id: number
}
function findById<T extends HasId>(items: T[], id: number): T | undefined {
return items.find(item => item.id === id)
}
- T代表什么类型,调用时才确定。
- extends限定类型边界,进得去出得来。
- 返回值和入参用同一个 T,类型才闭环。
泛型接口、泛型类同样常用。列表页的分页结果、网络层的统一响应,都可以抽成泛型容器,一处定义、处处复用。
装饰器:能力叠加的艺术
ArkTS 的 UI 开发里装饰器是骨架:@Entry 标记页面入口,@Component 定义组件,@State 声明响应式状态。理解装饰器「给类或成员附加元信息」的本质,才能用好它们。
@Entry
@Component
struct HomePage {
@State count: number = 0
build() {
Column() {
Text('点击了 ' + this.count + ' 次')
.fontSize(20)
Button('加一')
.onClick(() => { this.count++ })
}
.padding(24)
}
}
@State 的变化会驱动 build 重跑,这是声明式 UI 的心跳。区别「状态」和「普通字段」很重要:只有被装饰器标记的状态变化才会触发刷新,普通成员变了 UI 不会动。
高级类与接口模式
业务里最常见的三种结构:抽象类定骨架、接口定契约、实现类给细节。ArkTS 支持 implements 和 extends,组合它们可以让依赖方向保持稳定。
interface Repository<T> {
list(): Promise<T[]>
save(item: T): Promise<void>
}
abstract class BaseRepo<T> implements Repository<T> {
abstract table: string
async list(): Promise<T[]> { return this.queryAll() }
async save(item: T): Promise<void> { return this.insert(item) }
protected abstract queryAll(): Promise<T[]>
protected abstract insert(item: T): Promise<void>
}
依赖接口而不是具体类,测试时就能注入假实现。数据层、网络层、业务层之间用接口隔开,替换实现不影响上层调用方。
状态联动与数据代理
组件多了,状态不能各自为政。把共享状态提升到父组件,用 @Prop 和 @Link 传下去:@Prop 单向、@Link 双向。数据代理对象配合 @Observed,让嵌套对象的变化也能被感知。
@Observed
class CartItem {
count: number = 0
}
@Entry
@Component
struct CartPage {
@State cart: CartItem = new CartItem()
build() {
Column() {
Text('数量:' + this.cart.count)
Button('加购')
.onClick(() => { this.cart.count++ })
}
}
}
原则很简单:能局部就别全局,能单向就别双向。状态越靠近使用它的组件,重构越轻松;一旦发现多个组件都要读写同一份数据,再考虑提升或抽出独立数据层。
工程化:模块、规范与可测试性
进阶的最后一公里是工程化。按模块拆目录、统一命名、把纯逻辑抽成不依赖 UI 的函数,测试才写得动。ArkTS 里纯函数和类的单元测试,用 DevEco Studio 的测试框架就能跑。
// 纯逻辑抽出来,UI 不掺和
export function calcTotal(items: CartItem[]): number {
return items.reduce((sum, item) => sum + item.count, 0)
}
// 组件只负责展示和转发事件
struct CartSummary {
total: number
onCheckout: () => void
build() {
Row() {
Text('合计 ' + this.total)
Button('结算').onClick(this.onCheckout)
}
}
}
目录按 feature 组织而不是按类型堆叠:每个功能模块自带页面、数据、工具。改一个需求只动一个目录,回归范围肉眼可见。
小结
进阶 ArkTS 靠四件事:泛型把类型用到极致、装饰器理解响应式骨架、接口与抽象类稳住架构、工程化让代码可测可维护。语言特性学完只是起点,真正的进阶发生在你用它约束住一个又一个真实的业务问题时。把类型当作设计工具,把装饰器当作状态契约,小项目也会长出大项目的底气。