编程TypeScript 开发者

什么是 TypeScript 中的字面量类型,它们的用途是什么?如何通过它们实现对变量值的严格限制,使用时会有哪些陷阱?

用 Hintsage AI 助手通过面试

字面量类型 允许将变量的可能值限制为某些特定的常量,而不是简单的通用类型(例如,不只是数字,而是数字 5 或字符串 "yes")。

这在创建具有固定参数、状态等的 API 时非常有用。

type Direction = 'left' | 'right' | 'up' | 'down'; function move(dir: Direction) { // ... } move('left'); // 好 move('top'); // 编译错误!

它还适用于数字、布尔值甚至完整的结构(元组字面量类型):

type WeekDay = 1 | 2 | 3 | 4 | 5 | 6 | 7; const day: WeekDay = 6; // 好

限制和细节:

  • 字面量类型不能隐式转换值(例如,不能将用户输入的字符串赋值给类型为 'left' | 'right' 的变量,而不进行检查)。
  • 在使用常量和 let 变量时,重要的是要记住输出类型:
const d = 'left'; // 类型为 'left' (字面量) let e = 'left'; // 类型为 string (普通)

有陷阱的问题

问题: 如果将变量定义为 const x = "yes";,那么它会获得什么类型?之后能否将其他字符串值赋给它?

答案:

  • 如果声明 const x = "yes"; — x 的类型将是 "yes" (字面量类型),并且它不能被赋值为任何其他值,除了 'yes'(因为 const,根本无法更改)。
  • 如果声明 let x = "yes";,则 x 将被类型为 string,可以赋值为任何字符串。
const x = 'yes'; // x: 'yes' let y = 'yes'; // y: string

由于对主题细节的不熟悉而导致的实际错误示例。


故事

在一个任务状态项目中使用了枚举,但开发人员用字符串替换了它。结果是,API 开始接受任何字符串作为状态,这在产品发展的过程中产生了许多错误,因为失去了控制。


故事

开发人员试图在数据验证中使用字面量类型,但直接将表单字段的参数赋值 — TS 允许这样做,因为输入字段的类型是字符串,而不是字面量(例如,"ok" | "fail"),因为输入值没有经过验证。最终在运行时出现了不在允许集合中的值。


故事

在为一个需要字面量值的函数编写测试时,自动生成的测试意外地提供了一个字符串参数,测试未通过。后来发现,由于在 let 声明时对类型输出的不注意,类型被放宽,编译器并没有捕捉到这个问题。