

























目标:掌握枚举、Type 别名、特殊类型与类型操作,理解 ArkTS 类型限制
预计时间:1-1.5小时
回顾前面学习的类型系统:
// 基本类型
let count: number = 10;
let name: string = "张三";
let active: boolean = true;
// 数组类型
let scores: number[] = [85, 92, 78];
// 接口类型
interface Person {
name: string;
age: number;
}
思考问题:
问题:魔法数字可读性差
// 不用枚举:0、1、2 代表什么?
let status: number = 0; // 离线?在线?故障?
function handleStatus(s: number): void {
if (s === 0) {
console.log("离线");
} else if (s === 1) {
console.log("在线");
} else if (s === 2) {
console.log("故障");
}
}
枚举解决方案:
enum DeviceStatus {
OFFLINE, // 0
ONLINE, // 1
ERROR // 2
}
let status: DeviceStatus = DeviceStatus.ONLINE;
console.log(`结果:${status}`); // 1
// 判断状态
if (status === DeviceStatus.ONLINE) {
console.log("设备在线");
}
自动递增规则:
enum Priority {
LOW, // 0
MEDIUM, // 1
HIGH // 2
}
// 显式指定初始值
enum Direction {
UP = 10, // 10
DOWN = 20, // 20
LEFT = 30, // 30
RIGHT = 40 // 40
}
// 部分指定,后续自动递增
enum Status {
PENDING = 1, // 1
PROCESSING, // 2
COMPLETED, // 3
FAILED // 4
}
enum LogLevel {
DEBUG = "DEBUG",
INFO = "INFO",
WARN = "WARN",
ERROR = "ERROR"
}
let level: LogLevel = LogLevel.INFO;
console.log(`结果:${level}`); // "INFO"
function logMessage(level: LogLevel, message: string): void {
console.log(`[${level}] ${message}`);
}
logMessage(LogLevel.ERROR, "连接超时"); // [ERROR] 连接超时
字符串枚举优势:
场景1:命令类型
enum CommandType {
TURN_ON = 0x01,
TURN_OFF = 0x02,
SET_BRIGHTNESS = 0x03,
GET_STATUS = 0x04
}
class DeviceController {
executeCommand(cmd: CommandType, param?: number): string {
if (cmd === CommandType.TURN_ON) {
return "设备已开启";
} else if (cmd === CommandType.TURN_OFF) {
return "设备已关闭";
} else if (cmd === CommandType.SET_BRIGHTNESS) {
return `亮度设置为 ${param}`;
} else if (cmd === CommandType.GET_STATUS) {
return "当前状态:正常";
}
return "未知命令";
}
}
场景2:状态机
enum ConnectionState {
DISCONNECTED,
CONNECTING,
CONNECTED,
RECONNECTING
}
class NetworkManager {
private state: ConnectionState = ConnectionState.DISCONNECTED;
connect(): void {
if (this.state === ConnectionState.DISCONNECTED) {
this.state = ConnectionState.CONNECTING;
// 执行连接...
}
}
}
❌ 禁止:混合类型枚举
// ❌ 编译错误:不能同时包含数字和字符串
enum MixedEnum {
A = 1, // number
B = "B" // string - 错误!
}
✅ 正确做法:
// 纯数值枚举
enum NumericEnum {
A = 1,
B = 2,
C = 3
}
// 纯字符串枚举
enum StringEnum {
A = "A",
B = "B",
C = "C"
}
对比 C++:
// C++11 推荐 enum class
enum class Status {
OFFLINE = 0,
ONLINE = 1,
ERROR = 2
};
Status s = Status::ONLINE; // 作用域更强
// 为基本类型起别名
type ID = number;
type Name = string;
type Price = number;
type IsActive = boolean;
// 使用
let userId: ID = 1001;
let productName: Name = "手机";
let productPrice: Price = 2999.99;
let status: IsActive = true;
作用:
// 定义有限的状态值
type Status = "pending" | "processing" | "completed" | "failed";
type Priority = "low" | "medium" | "high";
type Theme = "light" | "dark" | "auto";
// 使用
let taskStatus: Status = "pending";
let taskPriority: Priority = "high";
function updateStatus(newStatus: Status): void {
console.log(`状态更新为:${newStatus}`);
}
// 只能赋值预定义的值
// updateStatus("unknown"); // ❌ 编译错误
// 定义函数类型
type ClickHandler = (x: number, y: number) => void;
type DataTransformer = (input: string) => number;
type Validator = (value: string) => boolean;
// 使用
let handleClick: ClickHandler = (x: number, y: number): void => {
console.log(`点击位置:(${x}, ${y})`);
};
let parseNumber: DataTransformer = (input: string): number => {
return parseInt(input, 10);
};
let isEmail: Validator = (value: string): boolean => {
return value.indexOf("@") > 0;
};
// 在接口中使用
type CompareFn = (a: number, b: number) => number;
interface Sorter {
compare: CompareFn;
sort(data: number[]): number[];
}
❌ 禁止:用 type 定义对象类型
// ❌ ArkTS 编译错误
type Person = {
name: string;
age: number;
};
// ✅ 正确做法:使用 interface
interface Person {
name: string;
age: number;
}
❌ 禁止:交叉类型
interface A {
a: number;
}
interface B {
b: string;
}
// ❌ ArkTS 编译错误
type AB = A & B;
// ✅ 正确做法:使用接口继承
interface AB extends A, B {
// 自动包含 a 和 b
}
概念:表示"永远不会发生的值",是所有类型的子类型
使用场景1:抛出异常的函数返回类型
function throwError(message: string): never {
throw new Error(message);
}
使用场景2:穷尽检查(exhaustive check)
在 switch 的 default 分支中确保所有 case 都被处理:
enum Status {
PENDING = "pending",
SUCCESS = "success",
FAILED = "failed"
}
function handleStatus(status: Status): string {
switch (status) {
case Status.PENDING:
return "处理中...";
case Status.SUCCESS:
return "成功!";
case Status.FAILED:
return "失败!";
default:
// 穷尽检查:如果上面漏了某个 case,这里会编译报错
const check: never = status;
return check;
}
}
对比 C++:
// C++ 中 [[noreturn]] 属性标注的函数
[[noreturn]] void throwError(const std::string& message) {
throw std::runtime_error(message);
}
注意:
never和void的区别
void:表示没有返回值(函数正常结束)never:表示永远不会正常结束(抛出异常或无限循环)
概念:手动告诉编译器某个值的具体类型
语法:value as TargetType
使用场景:当你比编译器更了解某个值的实际类型时
示例:父类引用转换为子类类型(Day 10 已学继承,可以用这个场景)
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
move(): void {
console.log("动物在移动");
}
}
class Dog extends Animal {
bark(): void {
console.log("汪汪!");
}
}
// 父类引用指向子类对象
let animal: Animal = new Dog("旺财");
// 需要调用 Dog 特有的方法时,使用 as 断言
let dog: Dog = animal as Dog;
dog.bark(); // 汪汪!
⚠️ ArkTS 限制:as const 断言不支持(规则 arkts-no-as-const)
// ❌ ArkTS 不支持 as const
// let arr = [1, 2, 3] as const;
// ✅ ArkTS 正确写法
let arr: number[] = [1, 2, 3];
安全建议:优先使用 instanceof 类型守卫(Day 03 已学),as 断言是最后手段
// ✅ 更安全的做法:使用 instanceof
if (animal instanceof Dog) {
animal.bark(); // 类型守卫自动收窄为 Dog
}
对比 C++:
// 类似 C++ 的 static_cast,编译期检查但不保证运行时安全
Dog* dog = static_cast<Dog*>(animalPtr);
这一节集中说明 ArkTS 相比 TypeScript 不支持的类型特性,让你了解边界。
在标准 TypeScript 中,unknown 是 any 的安全替代——接收任何值但使用前必须类型检查。
ArkTS 同时禁用 any 和 unknown(规则 arkts-no-any-unknown)。
替代方案:使用显式的联合类型或 Object 类型
// ❌ TypeScript 的写法(ArkTS 不允许)
// let value: unknown = 42;
// ✅ ArkTS 的写法:用联合类型
let value: number | string = 42;
// 或者使用 Object 类型(需要时再进行类型判断)
let obj: Object = { name: "张三" };
在标准 TypeScript 中,可以用具体的字符串/数字值作为类型:
// ❌ TypeScript 的字面量类型(ArkTS 不允许)
// type Direction = "up" | "down" | "left" | "right";
ArkTS 不支持字面量类型(规则 arkts-no-as-const)。
替代方案:使用枚举(Day 13 第一部分已学)
// ✅ ArkTS 用枚举替代
enum Direction {
UP = "up",
DOWN = "down",
LEFT = "left",
RIGHT = "right"
}
let dir: Direction = Direction.UP;
console.log(`方向:${dir}`); // 方向:up
| 限制项 | 错误示例 | 正确做法 |
|---|---|---|
| 对象类型必须用 interface | type Person = {...} |
interface Person {...} |
| 禁止索引签名 | [key: string]: number |
使用 Record<K, V> 或 Map |
| 禁止交叉类型 | type AB = A & B |
interface AB extends A, B |
| interface 不支持 readonly | readonly x: number |
使用 Readonly<T> 工具类型 |
| 对象字面量需配合 interface | let x = {a: 1} |
let x: MyInterface = {...} |
interface Point {
x: number;
y: number;
}
// 创建只读版本
type ReadonlyPoint = Readonly<Point>;
let p1: Point = { x: 10, y: 20 };
p1.x = 100; // ✅ 可以修改
let p2: ReadonlyPoint = { x: 10, y: 20 };
// p2.x = 100; // ❌ 编译错误:只读属性
注意: Readonly<T> 是 ArkTS 提供的工具类型,Day 12 学习泛型后会理解其原理。
// 替代索引签名
let scores: Record<string, number> = {
"张三": 85,
"李四": 92
};
// 或使用 Map
let scoreMap: Map<string, number> = new Map();
scoreMap.set("张三", 85);
| 概念 | 核心语法 | 适用场景 |
|---|---|---|
| 枚举(Enum) | enum Status { A, B } |
有限常量值集合 |
| 数值枚举 | enum A { X = 1, Y } |
状态码、命令类型 |
| 字符串枚举 | enum B { X = "X" } |
日志级别、错误类型 |
| Type 别名 | type ID = number |
基本类型、联合类型、函数类型 |
| 联合类型 | type S = "a" | "b" |
有限字符串值 |
| 场景 | 推荐 |
|---|---|
| 有限常量值 | enum |
| 基本类型别名 | type |
| 联合类型 | type |
| 函数类型 | type |
| 对象类型 | interface(ArkTS 强制) |
| 扩展对象类型 | interface extends |
// 1. 定义 HttpStatus 枚举:
// - OK = 200
// - NOT_FOUND = 404
// - SERVER_ERROR = 500
// 2. 定义 UserRole 字符串枚举:
// - ADMIN = "admin"
// - USER = "user"
// - GUEST = "guest"
// 3. 编写函数 checkPermission(role: UserRole): boolean
// - ADMIN 返回 true
// - 其他返回 false
// 1. 定义以下类型别名:
// - UserId: number
// - Email: string
// - ApiResponse: { code: number; data: object; message: string }
// 2. 定义 StatusCode 联合类型:
// - 200 | 404 | 500
// 3. 定义 Handler 函数类型:
// - (req: object) => ApiResponse
// 将以下不符合 ArkTS 规范的代码改写:
// 原代码(不符合规范):
type Config = {
key: string;
value: any;
[key: string]: any; // 索引签名
};
// 请改写为符合 ArkTS 规范的代码
| 特性 | C++ | ArkTS |
|---|---|---|
| 枚举 | enum / enum class |
enum(禁止混合类型) |
| 类型别名 | typedef / using |
type |
| 联合类型 | std::variant (C++17) |
type X = A | B |
| 函数类型 | 函数指针 / std::function |
type Fn = (...) => T |
| 对象类型 | struct / class |
interface |
| 交叉类型 | 多重继承 | 不支持(用接口继承) |
| never 类型 | [[noreturn]] |
never |
| 类型断言 | static_cast / dynamic_cast |
as(部分支持) |
| unknown 类型 | - | 不支持 |
| 字面量类型 | - | 不支持(用枚举替代) |
完成本课后,你将掌握:
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。