本文同步发表于 微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
区别对比
| 类型本质 | 类型契约,编译时概念 | 运行时实体,包含构造函数和方法 |
| 初始化方式 | 只能用对象字面量 {name: "张三", avatar: $r(…)} | 必须用构造函数 new Organization(…) 不能用字面量 |
| 原因 | 接口只是形状描述,没有实际实现 | 类有构造函数、方法、可能的继承关系等 |
| 可观察性 | 需要搭配 @Observed 装饰类 | 类本身可以用 @Observed 装饰 |
示例:接口 vs 类初始化
// ============ Employee 接口============
export interface Employee {
name: string;
avatar: ResourceStr;
}
// 接口初始化方式:对象字面量
const employee1: Employee = {
name: "张三",
avatar: $r('app.media.avatar1')
};
// ============ Organization 类============
@Observed
export class Organization {
icon: ResourceStr;
name: string;
expand: boolean;
employees: Employee[];
constructor(icon: ResourceStr, name: string, expand: boolean, employees: Employee[]) {
this.icon = icon;
this.name = name;
this.expand = expand;
this.employees = employees;
}
}
// 类初始化方式:构造函数
const org1: Organization = new Organization(
$r('app.media.dept_icon'),
"研发部",
true,
[employee1] // 这里传入了刚才用字面量创建的 Employee
);
// 错误:尝试用字面量初始化类(会编译错误)
const org2: Organization = {
icon: $r('app.media.dept_icon'),
name: "市场部",
expand: false,
employees: []
};
// 报错:Type '{ icon: ResourceStr; name: string; expand: boolean; employees: never[]; }'
// is missing the following properties from type 'Organization': [类特有的方法或属性]
为什么类不能用字面量初始化?
构造函数的逻辑:类有构造函数,可能包含初始化逻辑、参数验证、默认值设置等。
类可能有方法:
@Observed
export class Organization {
// … 属性同上
constructor(…) { /* … */ }
// 类特有的方法
toggleExpand(): void {
this.expand = !this.expand;
}
addEmployee(emp: Employee): void {
this.employees.push(emp);
}
}
如果允许字面量初始化,这些方法将不存在。
继承关系:如果 Organization 继承自另一个类,字面量无法处理父类的初始化。
实际项目中使用混合模式
通常会混合使用这两种方式:
// 初始化组织列表(包含类和接口)
@State organizationList: Organization[] = [
// 使用构造函数初始化类
new Organization(
$r('app.media.rd_icon'),
"技术研发部",
true,
[ // 这里用字面量数组初始化 Employee[] 接口数组
{ name: "张工程师", avatar: $r('app.media.avatar_zhang') },
{ name: "李架构师", avatar: $r('app.media.avatar_li') }
]
),
new Organization(
$r('app.media.sales_icon'),
"销售部",
false,
[ // 继续使用接口字面量
{ name: "王销售", avatar: $r('app.media.avatar_wang') }
]
)
];
特殊情况:如果想让类支持字面量初始化
如果希望 让类Organization 也能用字面量初始化,可以:
使用类型断言(不推荐,绕过类型检查)
const org = {
icon: $r('app.media.icon'),
name: "测试部",
expand: true,
employees: []
} as Organization; // 强制类型断言
接口用字面量初始化,类用构造函数初始化,这是TypeScript/ArkTS的类型系统设计。既利用了接口的简洁性,又通过类获得了可观察性和扩展性。





