字面量类型与联合类型
定义一个接口,它描述了响应的消息结构:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论