解析鸿蒙 ArkTS 中的 Union 类型与 TypeAliases类型

在鸿蒙 ArkTS(基于 TypeScript 的扩展)中,Union 类型Type Aliases(类型别名) 是类型系统的两大核心特性。它们虽然常被同时使用,但解决的问题截然不同。本文将通过完整示例深入剖析二者的区别与应用场景。


一、Union 类型:灵活的多类型容器

核心概念 :允许变量持有多种类型中的任意一种 ,使用 | 符号组合类型。

关键特性

  • 运行时需类型保护(typeof/instanceof
  • 增强 API 灵活性
  • 完美处理可选值(如 T | null

完整示例

typescript 复制代码
// 1. 基础类型联合
type Primitive = string | number | boolean;
const logValue = (value: Primitive) => {
  if (typeof value === "string") {
    console.log(value.toUpperCase());
  } else {
    console.log(value.toFixed(2)); // 自动推断为 number | boolean
  }
};

// 2. 对象类型联合
class Cat {
  meow() { console.log("Meow!") }
}

class Dog {
  bark() { console.log("Woof!") }
}

type Pet = Cat | Dog;

const handlePet = (pet: Pet) => {
  if (pet instanceof Cat) {
    pet.meow();  // 类型保护
  } else {
    pet.bark();  // 自动推断为 Dog
  }
};

// 3. 带字面量的联合
type Status = "loading" | "success" | "error";
const setStatus = (status: Status) => {
  console.log(`Current status: ${status}`);
};

典型应用场景

  1. 函数参数支持多类型:parseInput(input: string | number)
  2. 状态机表示:type State = "idle" | "running" | "paused"
  3. 网络响应处理:type Response = SuccessData | ErrorInfo

二、Type Aliases:类型系统的快捷方式

核心概念 :为现有类型创建可复用的别名 ,使用 type 关键字定义。

关键特性

  • 简化复杂类型声明
  • 提升代码可读性
  • 实现 DRY(Don't Repeat Yourself)原则

完整示例

typescript 复制代码
// 1. 简化复杂结构
type UserProfile = {
  id: string;
  name: string;
  preferences: {
    theme: "light" | "dark";
    notifications: boolean;
  };
};

const updateProfile = (profile: UserProfile) => {
  /* 实现细节 */
};

// 2. 函数类型签名
type FetchHandler = (
  url: string, 
  options: { timeout: number; retries: number }
) => Promise<Response>;

const fetchData: FetchHandler = async (url, opts) => {
  /* 实现细节 */
};

// 3. 元组类型简化
type Point3D = [number, number, number];
const calculateDistance = (p1: Point3D, p2: Point3D) => {
  /* 三维空间计算 */
};

// 4. 泛型别名
type ApiResponse<T> = {
  data: T;
  timestamp: Date;
  statusCode: number;
};

const userResponse: ApiResponse<UserProfile> = await fetchUser();

典型应用场景

  1. 统一项目类型规范:type UserID = string
  2. 简化复杂对象结构
  3. 自文档化代码(见名知意)
  4. 泛型类型模板

三、黄金组合:Union 与 Alias 的协作

二者结合使用能最大化类型系统的优势:

typescript 复制代码
// 1. 联合类型别名化
type Identifier = string | number | { id: string };

// 2. 复杂联合结构
type NetworkState =
  | { status: "idle" }
  | { status: "loading"; progress: number }
  | { status: "success"; data: ApiResponse<any> }
  | { status: "error"; code: number };

// 3. 类型安全的Redux模式
type Action = 
  | { type: "ADD_TODO"; text: string }
  | { type: "TOGGLE_TODO"; id: number }
  | { type: "DELETE_TODO"; id: number };

const reducer = (state: Todo[], action: Action) => {
  switch (action.type) {
    case "ADD_TODO":
      // action.text 可用
      return [...state, { text: action.text }];
    case "TOGGLE_TODO":
      // action.id 可用
      return state.map(todo => 
        todo.id === action.id ? { ...todo, done: !todo.done } : todo
      );
    // 无需 default case(类型穷尽检查)
  }
};

四、核心差异总结

| 特性 | Union 类型 | Type Aliases |
|-----------|--------------|------------------|------------|
| 本质 | 类型组合(逻辑或) | 类型重命名 |
| 主要目的 | 扩展变量允许的类型范围 | 简化复杂类型声明 |
| 运行时影响 | 需要类型保护机制 | 纯编译时概念 |
| 典型符号 | ` | `(管道符) | type 关键字 |
| 最佳实践 | 处理不确定类型的场景 | 创建领域特定语言(DSL) |
| 嵌套能力 | 可包含其他联合类型 | 可封装任意类型(包括联合) |


五、何时使用哪种类型?

选择 Union 类型当

  • 需要处理多种可能的输入类型
  • 构建状态机或复杂工作流
  • 变量可能为不同类型(如 string | null

选择 Type Alias 当

  • 重复使用复杂类型结构
  • 提升代码可读性(如 type Coordinate = [number, number]
  • 统一项目类型规范
  • 创建自解释的API签名

组合使用场景

  1. 为联合类型创建有意义的别名:
    type CardType = "visa" | "mastercard" | "amex"

  2. 简化包含联合的复杂结构:

    typescript 复制代码
    type PaymentMethod = {
      type: CardType;
      last4: string;
      expiry: Date;
    }

六、高级技巧:类型操作

typescript 复制代码
// 1. 联合类型提取
type StringOrNumber = string | number;
type ExtractString<T> = T extends string ? T : never;
type Result = ExtractString<StringOrNumber>; // = string

// 2. 条件类型分发
type ToArray<T> = T extends any ? T[] : never;
type NumOrStrArray = ToArray<number | string>; // = number[] | string[]

// 3. 模板字面量类型(ArkTS 4.0+)
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
type ApiEndpoint = `/api/${string}`;
type FullRoute = `${HttpMethod} ${ApiEndpoint}`;

总结

  • Union 类型 是类型系统的 "或运算符",扩展值的可能性
  • Type Aliases 是类型系统的 "命名工具",提升代码表达能力
  • 二者结合 能构建精确灵活的领域模型

在鸿蒙应用开发中:

typescript 复制代码
// 典型ArkTS组件属性模式
type ButtonProps = {
  text: string;
  size: "small" | "medium" | "large";
  onPress: () => void;
  style?: StyleProp; // 联合类型 + 可选
};

@Entry
@Component
struct MyButton {
  @Prop config: ButtonProps; // 类型别名复用
  
  build() {
    Button(this.config.text)
      .onClick(() => this.config.onPress?.())
  }
}

掌握这两种类型特性,将使你的鸿蒙应用获得更强的类型安全保障和更优雅的代码架构。

相关推荐
coding随想31 分钟前
JavaScript ES6 解构:优雅提取数据的艺术
前端·javascript·es6
小小小小宇36 分钟前
一个小小的柯里化函数
前端
灵感__idea40 分钟前
JavaScript高级程序设计(第5版):无处不在的集合
前端·javascript·程序员
小小小小宇43 分钟前
前端双Token机制无感刷新
前端
小小小小宇1 小时前
重提React闭包陷阱
前端
小小小小宇1 小时前
前端XSS和CSRF以及CSP
前端
UFIT1 小时前
NoSQL之redis哨兵
java·前端·算法
超级土豆粉1 小时前
CSS3 的特性
前端·css·css3
星辰引路-Lefan1 小时前
深入理解React Hooks的原理与实践
前端·javascript·react.js
wyn200011281 小时前
JavaWeb的一些基础技术
前端