返回介绍

字面量类型与联合类型

发布于 2024-09-11 00:55:47 字数 2983 浏览 0 评论 0 收藏 0

定义一个接口,它描述了响应的消息结构:

interface IResponseProps {
  code: number;
  status: string;
  data: any;
}

这里的 code 与 status 实际值会来自于一组确定值的集合,比如 code 可能是 10000 / 10001 / 50000,status 可能是 "success" / "failure"。

上面的类型只给出了一个宽泛的 number / string,既不能在访问 code 时获得精确的提示,也失去了 TypeScript 类型即文档的功能。

可以使用字面量类型加上联合类型进行改写:

interface IResponseProps {
  code: 10000 | 10001 | 50000;
  status: 'success' | 'failure';
  data: any;
}

这时就能在访问时获得精确地类型推导了。

对于 declare var res: Res,它是快速生成一个符合指定类型,但没有实际值的变量,同时它也不存在于运行时中。

字面量类型

"success" 不是一个值吗?为什么它可以作为类型?在 TypeScript 中,这叫做字面量类型(Literal Types),它代表着比原始类型更精确的类型,同时也是原始类型的子类型。

字面量类型主要包括字符串字面量类型、数字字面量类型、布尔字面量类型和对象字面量类型。

const name: 'wangxiaobai' = 'wangxiaobai';
const age: 18 = 18;
const male: false = false;

为什么说字面量类型比原始类型更精确?

// 报错!不能将类型“"wangxiaobai18"”分配给类型“"wangxiaobai"”。
const str1: 'wangxiaobai' = 'wangxiaobai18';
const str2: string = 'wangxiaobai';
const str3: string = 'wangxiaobai3';

原始类型的值可以包括任意的同类型值,而字面量类型要求的是值级别的字面量一致。

单独使用字面量类型比较少见,因为单个字面量类型并没有什么实际意义。它通常和联合类型(即这里的 |)一起使用,表达一组字面量类型:

interface ITempProps {
  bool: true | false;
  num: 1 | 2 | 3;
  str: 'wang' | 'xiao' | 'bai'
}

联合类型

它代表了一组类型的可用集合,只要最终赋值的类型属于联合类型的成员之一,就可以认为符合这个联合类型。

联合类型对其成员并没有任何限制,除了上面这样对同一类型字面量的联合,还可以将各种类型混合到一起。

interface ITempMixedProps {
  mixed: true | string | 18 | {} | (() => {}) | (1 | 2)
}

这里有几点需要注意:

  • 联合类型中的函数类型需要使用括号 () 包裹起来
  • 函数类型并不存在字面量类型,因此这里的 (() => {}) 就是一个合法的函数类型
  • 可以在联合类型中进一步嵌套联合类型,但这些嵌套的联合类型最终都会被展平到第一级中

常用场景之一是通过多个对象类型的联合,来实现手动的互斥属性,即这一属性如果有字段 1,那就没有字段 2。

interface ITempProps {
  user:
    | {
    vip: true;
    expires: string;
  }
  | {
    vip: false;
    promotion: string;
  }
}

declare var temp: ITempProps;

if (temp.user.vip) {
  console.log(temp.user.expires);
}

user 属性会满足普通用户与 VIP 用户两种类型,这里 vip 属性的类型基于布尔字面量类型声明。

在实际使用时可以通过判断此属性为 true,确保接下来的类型推导都会将其类型收窄到 VIP 用户的类型(即联合类型的第一个分支)。

可以通过类型别名来复用一组字面量联合类型:

type Code = 10000 | 10001 | 50000;
type Status = 'success' | 'failure';

除了原始类型的字面量类型以外,对象类型也有着对应的字面量类型。

对象字面量类型

对象字面量类型就是一个对象类型的值,这也就意味着这个对象的值全都为字面量值。

interface ITempProps {
  obj: {
    name: 'wangxiaobai';
    age: 18
  }
}

const temp: ITempProps = {
  obj: {
    name: 'wangxiaobai',
    age: 18
  }
}

如果要实现一个对象字面量类型,意味着完全的实现这个类型每一个属性的每一个值。

无论是原始类型还是对象类型的字面量类型,它们的本质都是类型而不是值。在编译时同样会被擦除,同时也是被存储在内存中的类型空间而非值空间。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文