首页  >  文章  >  web前端  >  TypeScript 标记的联合是 OP

TypeScript 标记的联合是 OP

Linda Hamilton
Linda Hamilton原创
2024-10-10 06:17:29317浏览

TypeScript Tagged Unions are OP

曾经在 TypeScript 中处理多个对象形状时遇到过困难,并希望有一个更类型安全的解决方案吗?

如果是这样,你并不孤单。许多开发人员没有意识到标记联合(也称为歧视联合)在 TypeScript 中提供的全部潜力。这一强大的功能可以增强代码的安全性、可读性和可维护性。在本文中,我们将深入研究标记联合并探索它们如何提高您的 TypeScript 技能。

?️ 什么是标记联合?

标记联合允许您创建代表几种可能形状之一的类型,每个形状都具有称为“标记”或“鉴别器”的区别属性。这使得 TypeScript 能够缩小条件检查中的类型范围,确保您的代码显式处理所有可能的情况。

?为什么你应该关心?

增强类型安全性

标记联合通过确保处理所有可能的情况来帮助在编译时捕获错误。这可以减少运行时错误并使您的代码更加健壮。

清晰且可维护的代码

通过显式定义每个案例的形状,您的代码将变得更具可读性并且更易于维护。未来的开发者(甚至未来的你)会感谢你!

详尽性检查

如果您忘记处理可能的情况,TypeScript 可以向您发出警告,确保您的代码考虑到所有场景。

?通过示例标记工会

考虑一个场景,您有不同的形状并想要计算它们的面积:

// Define interfaces with a discriminant property 'kind'
interface Circle {
  kind: 'circle';
  radius: number;
}

interface Rectangle {
  kind: 'rectangle';
  width: number;
  height: number;
}

interface Triangle {
  kind: 'triangle';
  base: number;
  height: number;
}

// Create a union type of all shapes
type Shape = Circle | Rectangle | Triangle;

// Function to calculate the area based on shape kind
function calculateArea(shape: Shape): number {
  switch (shape.kind) {
    case 'circle':
      return Math.PI * shape.radius ** 2;

    case 'rectangle':
      return shape.width * shape.height;

    case 'triangle':
      return (shape.base * shape.height) / 2;

    default:
      // The 'never' type ensures all cases are handled
      const _exhaustiveCheck: never = shape;
      return _exhaustiveCheck;
  }
}

这里发生了什么?

  • 判别属性(kind):每个接口都包含一个具有文字类型的kind属性。该属性充当联合的标签。
  • 联合类型(形状):将所有形状接口组合成一个类型。
  • 类型缩小:在 switch 语句中,TypeScript 根据 kind 属性准确地知道它正在处理哪种形状。
  • 详尽性检查:具有 never 类型的默认情况可确保如果添加新形状但未处理,TypeScript 将产生编译时错误。

?️ 示例:状态管理

标记联合在状态管理场景中非常有用,例如表示异步操作的各种状态(例如,数据获取)。

interface LoadingState {
  status: 'loading';
}

interface SuccessState {
  status: 'success';
  data: string;
}

interface ErrorState {
  status: 'error';
  error: string;
}

type AppState = LoadingState | SuccessState | ErrorState;

function renderApp(state: AppState) {
  switch (state.status) {
    case 'loading':
      return 'Loading...';
    case 'success':
      return `Data: ${state.data}`;
    case 'error':
      return `Error: ${state.error}`;
    // default case can be omitted because typescript is making sure all cases are covered!
  }
}

?为什么这很好?

  • 清晰的状态表示:每个界面代表应用程序的不同状态,使其易于理解和管理。

  • 数据访问的类型安全:当状态为“成功”时,TypeScript 知道该状态具有数据属性。类似地,当状态为“错误”时,它知道错误属性。这可以防止您意外访问给定状态下不存在的属性。

  • 详尽检查:如果添加新状态(例如状态为“empty”的 EmptyState),TypeScript 将提醒您在 renderApp 函数中处理这个新情况。

  • 提高可维护性:随着应用程序的增长,管理不同的状态变得更加易于管理。代码某一部分的更改会提示其他地方进行必要的更新,从而减少错误。

?使用标记联合的技巧

一致的鉴别器:在所有类型中使用相同的属性名称(例如类型、种类或状态)。
文字类型:确保鉴别器属性使用文字类型(“电子邮件”、“短信”等)以实现准确的类型缩小。
避免字符串枚举:对于鉴别器,优先使用字符串文字类型而不是枚举,以保持类型缩小的直接性。

?结论

标记联合是 TypeScript 中的一项强大功能,可以帮助您编写更安全、更易于维护的代码。通过显式处理每种可能的类型,您可以减少出现意外错误的机会并使代码更易于理解。

在当前或下一个 TypeScript 项目中尝试标记联合并亲身体验其好处!

?进一步阅读

  • TypeScript 手册:并集和交集类型
  • 什么是 TypeScript 可区分联合?

以上是TypeScript 标记的联合是 OP的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn