在 TypeScript 中,字面量类型(Literal Types)是一种特殊的类型,它允许你将变量的类型限制为某个具体的值(如特定的字符串、数字或布尔值),而不仅仅是宽泛的类型(如 string
、number
)。字面量类型通常与联合类型(Union Types)结合使用,用于创建更精确的类型约束。
一、字面量类型的三种形式
1. 字符串字面量类型
将变量的类型限制为特定字符串值:
let direction: "up" | "down" | "left" | "right";
direction = "up"; // ✅ 合法
direction = "north"; // ❌ 错误:不能将类型 'north' 分配给类型 '"up" | "down" | "left" | "right"'
2. 数字字面量类型
将变量的类型限制为特定数值:
let httpStatusCode: 200 | 404 | 500;
httpStatusCode = 200; // ✅ 合法
httpStatusCode = 403; // ❌ 错误:不能将类型 '403' 分配给类型 '200 | 404 | 500'
3. 布尔字面量类型
将变量的类型限制为 true
或 false
(实际用途较少,因为直接使用 boolean
更常见):
let isDone: true;
isDone = true; // ✅ 合法
isDone = false; // ❌ 错误:不能将类型 'false' 分配给类型 'true'
二、字面量类型的应用场景
1. 函数参数的精确类型约束
function setAlignment(align: "left" | "center" | "right") {// ...
}setAlignment("center"); // ✅ 合法
setAlignment("justify"); // ❌ 错误
2. 状态机或配置对象
type ButtonState = "enabled" | "disabled" | "loading";const button: { state: ButtonState } = {state: "enabled" // 只能是三种状态之一
};
3. 类型守卫与条件类型
结合类型守卫,根据字面量类型执行不同逻辑:
type Shape = | { kind: "circle"; radius: number }| { kind: "square"; sideLength: number };function getArea(shape: Shape) {if (shape.kind === "circle") {return Math.PI * shape.radius ** 2; // TypeScript 知道 shape 是圆形}// 无需 else 分支,TypeScript 自动推导 shape 是方形return shape.sideLength ** 2;
}
三、字面量类型与联合类型的结合
字面量类型的强大之处在于与联合类型结合,创建更灵活的类型系统:
type ResponseFormat = "json" | "xml" | { custom: string };function fetchData(format: ResponseFormat) {if (typeof format === "string") {// format 是 "json" 或 "xml"} else {// format 是 { custom: string }}
}
四、字面量类型的推断与缩小
1. 类型推断
// 推断为 "hello"(字符串字面量类型)
const greeting = "hello";// 推断为 string(因为变量可重新赋值)
let message = "hello";
message = "world"; // 合法
2. 类型缩小(Type Narrowing)
通过条件判断将宽泛类型缩小为字面量类型:
function printID(id: number | string) {if (typeof id === "string") {console.log(id.toUpperCase()); // id 被缩小为 string 类型} else {console.log(id.toFixed(2)); // id 被缩小为 number 类型}
}
五、字面量类型的进阶用法
1. 模板字面量类型(Template Literal Types)
基于字符串字面量组合出新的类型:
type Color = "red" | "blue";
type Size = "small" | "large";
type ProductID = `${Color}-${Size}`; // "red-small" | "red-large" | "blue-small" | "blue-large"
2. 字面量类型与枚举(Enum)的对比
- 枚举:编译后存在于运行时,可被修改。
- 字面量类型:仅存在于类型系统,编译后消失,更轻量。
// 枚举
enum Direction { Up, Down, Left, Right }
const d: Direction = Direction.Up;// 字面量类型
type DirectionLiteral = "up" | "down" | "left" | "right";
const dl: DirectionLiteral = "up";
总结:字面量类型的核心价值
- 精确性:将变量类型约束到具体值,增强类型安全性。
- 可读性:代码中明确声明允许的值,减少歧义。
- 与其他特性结合:联合类型、条件类型、模板字面量类型等,构建复杂类型系统。