字面量类型

字面量类型指定具体的值,而不是类型范围。TypeScript 支持字符串字面量类型、数字字面量类型和布尔字面量类型。字面量类型与联合类型结合使用,可以精确控制变量可以接受的值。

字符串字面量类型

字符串字面量类型限制变量只能是特定的字符串值。

type Direction = "up" | "down" | "left" | "right"

function move(direction: Direction): void {
  console.log(`向 ${direction} 移动`)
}

move("up")
move("down")

Direction 只能是四个字符串值之一,其他字符串会报错。

数字字面量类型

数字字面量类型限制变量只能是特定的数字值。

type Dice = 1 | 2 | 3 | 4 | 5 | 6

function roll(): Dice {
  return Math.floor(Math.random() * 6 + 1) as Dice
}

console.log(roll())
console.log(roll())

Dice 只能是 1 到 6 的数字,表示骰子的点数。

布尔字面量类型

布尔字面量类型限制变量只能是 truefalse

type Yes = true
type No = false

function answer(value: Yes | No): string {
  return value ? "是" : "否"
}

console.log(answer(true))
console.log(answer(false))

布尔字面量类型通常与联合类型一起使用。

联合字面量类型

字面量类型常与联合类型结合使用。

type Status = "pending" | "approved" | "rejected"
type HttpStatus = 200 | 201 | 400 | 404 | 500

function updateStatus(status: Status): void {
  console.log(`状态更新为: ${status}`)
}

function handleResponse(code: HttpStatus): void {
  console.log(`HTTP 状态码: ${code}`)
}

updateStatus("approved")
handleResponse(200)

联合字面量类型提供了精确的值限制。

字面量类型推断

TypeScript 会根据值自动推断字面量类型。

const direction = "up"

function move(dir: "up" | "down"): void {
  console.log(`移动方向: ${dir}`)
}

move(direction)

const 声明的变量会被推断为字面量类型,let 声明的变量会被推断为更宽泛的类型。

字面量类型拓宽

使用 letvar 声明时,类型会被拓宽。

const constantString = "hello"
let variableString = "hello"

type ConstantType = typeof constantString
type VariableType = typeof variableString

constantString 的类型是 "hello"variableString 的类型是 string

字面量类型与对象

对象属性可以是字面量类型。

interface User {
  role: "admin" | "user" | "guest"
  status: "active" | "inactive"
}

const admin: User = {
  role: "admin",
  status: "active"
}

const guest: User = {
  role: "guest",
  status: "inactive"
}

console.log(admin.role)
console.log(guest.status)

对象的 rolestatus 属性只能是特定的值。

字面量类型与函数

函数参数和返回值可以使用字面量类型。

type Method = "GET" | "POST" | "PUT" | "DELETE"

function request(method: Method, url: string): void {
  console.log(`${method} 请求: ${url}`)
}

request("GET", "/api/users")
request("POST", "/api/users")

method 参数只能是四个 HTTP 方法之一。

模板字面量类型

TypeScript 4.1 引入了模板字面量类型。

type EventName = "click" | "focus" | "blur"
type HandlerName = `on${Capitalize<EventName>}`

type Handlers = {
  [K in HandlerName]: () => void
}

const handlers: Handlers = {
  onClick: () => console.log("点击"),
  onFocus: () => console.log("获得焦点"),
  onBlur: () => console.log("失去焦点")
}

handlers.onClick()

模板字面量类型可以动态生成类型字符串。

实际应用

字面量类型在实际开发中常用于定义配置和状态。

type Environment = "development" | "staging" | "production"

interface Config {
  env: Environment
  debug: boolean
  apiUrl: string
}

const config: Config = {
  env: "development",
  debug: true,
  apiUrl: "http://localhost:3000"
}

function initApp(config: Config): void {
  console.log(`初始化应用,环境: ${config.env}`)
  console.log(`API 地址: ${config.apiUrl}`)
}

initApp(config)

Environment 限制了配置的环境值,确保配置的正确性。

小结

字面量类型指定具体的值,包括字符串字面量、数字字面量和布尔字面量。字面量类型常与联合类型结合使用,精确控制变量可以接受的值。const 声明的变量会被推断为字面量类型,let 声明的变量会被拓宽。模板字面量类型可以动态生成类型字符串。字面量类型在定义配置和状态时特别有用。