TypeScript字面量类型 #
一、字面量类型基础 #
1.1 什么是字面量类型 #
字面量类型是TypeScript中更精确的类型,它指定变量只能是某个具体的值。
typescript
let name: 'TypeScript';
name = 'TypeScript';
name = 'JavaScript';
1.2 字面量类型的种类 #
- 字符串字面量类型
- 数字字面量类型
- 布尔字面量类型
- 模板字面量类型(TypeScript 4.1+)
二、字符串字面量类型 #
2.1 基本用法 #
typescript
type Direction = 'up' | 'down' | 'left' | 'right';
function move(dir: Direction): void {
console.log(`Moving ${dir}`);
}
move('up');
move('down');
move('forward');
2.2 与联合类型结合 #
typescript
type EventName = 'click' | 'dblclick' | 'mousedown' | 'mouseup' | 'mouseover';
function addEventListener(event: EventName, handler: () => void): void {
document.addEventListener(event, handler);
}
2.3 实际应用 #
typescript
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
async function request(url: string, method: HttpMethod): Promise<Response> {
return fetch(url, { method });
}
await request('/api/users', 'GET');
await request('/api/users', 'POST');
await request('/api/users', 'INVALID');
2.4 状态管理 #
typescript
type Status = 'pending' | 'approved' | 'rejected';
interface Task {
id: number;
name: string;
status: Status;
}
function updateStatus(task: Task, status: Status): Task {
return { ...task, status };
}
const task: Task = {
id: 1,
name: 'Complete project',
status: 'pending'
};
updateStatus(task, 'approved');
三、数字字面量类型 #
3.1 基本用法 #
typescript
type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
let digit: Digit = 5;
digit = 10;
3.2 常见应用 #
typescript
type HttpStatus = 200 | 201 | 400 | 401 | 403 | 404 | 500;
function handleResponse(status: HttpStatus): string {
switch (status) {
case 200:
return 'OK';
case 201:
return 'Created';
case 400:
return 'Bad Request';
case 401:
return 'Unauthorized';
case 403:
return 'Forbidden';
case 404:
return 'Not Found';
case 500:
return 'Internal Server Error';
}
}
3.3 配置选项 #
typescript
type Port = 3000 | 8080 | 8000;
type Timeout = 1000 | 3000 | 5000 | 10000;
interface Config {
port: Port;
timeout: Timeout;
}
const config: Config = {
port: 3000,
timeout: 5000
};
四、布尔字面量类型 #
4.1 基本用法 #
typescript
type True = true;
type False = false;
let isTrue: True = true;
let isFalse: False = false;
isTrue = false;
4.2 实际应用 #
typescript
interface ButtonProps {
disabled: false;
loading: true;
}
interface InputProps {
disabled: true;
readonly: true;
}
type FeatureFlag = {
enabled: true;
beta: false;
};
4.3 条件类型 #
typescript
type IsString<T> = T extends string ? true : false;
type A = IsString<string>;
type B = IsString<number>;
五、模板字面量类型 #
5.1 基本语法 #
typescript
type EventName = `on${string}`;
let click: EventName = 'onClick';
let focus: EventName = 'onFocus';
let invalid: EventName = 'click';
5.2 结合联合类型 #
typescript
type Color = 'red' | 'blue' | 'green';
type Size = 'small' | 'medium' | 'large';
type ColorSize = `${Color}-${Size}`;
let style: ColorSize = 'red-small';
style = 'blue-large';
style = 'yellow-medium';
5.3 内置工具类型 #
TypeScript提供了内置的字符串操作类型:
typescript
type Greeting = 'hello world';
type Upper = Uppercase<Greeting>;
type Lower = Lowercase<Greeting>;
type Capital = Capitalize<Greeting>;
type Uncapital = Uncapitalize<Greeting>;
5.4 实际应用 #
typescript
type HttpMethod = 'get' | 'post' | 'put' | 'delete';
type ApiMethod = `api${Capitalize<HttpMethod>}`;
let method: ApiMethod = 'apiGet';
method = 'apiPost';
5.5 生成getter/setter #
typescript
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type Setters<T> = {
[K in keyof T as `set${Capitalize<string & K>}`]: (value: T[K]) => void;
};
interface Person {
name: string;
age: number;
}
type PersonGetters = Getters<Person>;
type PersonSetters = Setters<Person>;
六、字面量推断 #
6.1 类型推断 #
typescript
const str = 'hello';
let str2 = 'hello';
function greet(str: 'hello' | 'world') {
console.log(str);
}
greet('hello');
6.2 as const断言 #
使用as const将类型推断为字面量类型:
typescript
const str = 'hello' as const;
const arr = [1, 2, 3] as const;
const obj = {
name: 'TypeScript',
version: 5.4
} as const;
6.3 应用场景 #
typescript
const routes = ['/home', '/about', '/contact'] as const;
type Route = typeof routes[number];
function navigate(route: Route): void {
console.log(`Navigating to ${route}`);
}
navigate('/home');
navigate('/invalid');
七、字面量类型收窄 #
7.1 switch语句 #
typescript
type Shape = 'circle' | 'square' | 'triangle';
function getArea(shape: Shape): number {
switch (shape) {
case 'circle':
return Math.PI;
case 'square':
return 1;
case 'triangle':
return 0.5;
}
}
7.2 if语句 #
typescript
type Status = 'pending' | 'approved' | 'rejected';
function process(status: Status): void {
if (status === 'pending') {
console.log('Waiting for approval');
} else if (status === 'approved') {
console.log('Approved!');
} else {
console.log('Rejected');
}
}
7.3 对象属性收窄 #
typescript
interface Circle {
kind: 'circle';
radius: number;
}
interface Square {
kind: 'square';
sideLength: number;
}
type Shape = Circle | Square;
function getArea(shape: Shape): number {
if (shape.kind === 'circle') {
return Math.PI * shape.radius ** 2;
} else {
return shape.sideLength ** 2;
}
}
八、实用示例 #
8.1 CSS属性 #
typescript
type Position = 'static' | 'relative' | 'absolute' | 'fixed' | 'sticky';
type Display = 'block' | 'inline' | 'inline-block' | 'flex' | 'grid' | 'none';
type Overflow = 'visible' | 'hidden' | 'scroll' | 'auto';
interface CSSProperties {
position?: Position;
display?: Display;
overflow?: Overflow;
}
8.2 表单验证 #
typescript
type ValidationRule = 'required' | 'email' | 'url' | 'number' | 'minLength' | 'maxLength';
interface FieldConfig {
name: string;
rules: ValidationRule[];
}
const emailField: FieldConfig = {
name: 'email',
rules: ['required', 'email']
};
8.3 事件系统 #
typescript
type MouseEventType = 'click' | 'dblclick' | 'mousedown' | 'mouseup' | 'mousemove';
type KeyboardEventType = 'keydown' | 'keyup' | 'keypress';
type EventType = MouseEventType | KeyboardEventType;
function on(element: HTMLElement, event: EventType, handler: EventListener): void {
element.addEventListener(event, handler);
}
8.4 API路由 #
typescript
type ApiVersion = 'v1' | 'v2' | 'v3';
type Resource = 'users' | 'posts' | 'comments';
type ApiEndpoint = `/api/${ApiVersion}/${Resource}`;
let endpoint: ApiEndpoint = '/api/v1/users';
endpoint = '/api/v2/posts';
endpoint = '/api/v4/users';
九、字面量类型vs枚举 #
9.1 字面量类型 #
typescript
type Direction = 'up' | 'down' | 'left' | 'right';
function move(dir: Direction): void {
console.log(dir);
}
9.2 枚举 #
typescript
enum Direction {
Up = 'up',
Down = 'down',
Left = 'left',
Right = 'right'
}
function move(dir: Direction): void {
console.log(dir);
}
9.3 选择建议 #
| 场景 | 推荐 |
|---|---|
| 简单的值集合 | 字面量类型 |
| 需要反向映射 | 枚举 |
| 需要运行时遍历 | 枚举 |
| 最小化代码 | 字面量类型 |
| 需要独立命名空间 | 枚举 |
十、总结 #
本章介绍了TypeScript字面量类型:
字面量类型种类 #
- 字符串字面量:精确的字符串值
- 数字字面量:精确的数字值
- 布尔字面量:true或false
- 模板字面量:字符串模板组合
最佳实践 #
- 使用字面量类型定义精确的值集合
- 结合联合类型创建可辨识联合
- 使用
as const获得字面量类型推断 - 使用模板字面量类型生成类型
- 根据场景选择字面量类型或枚举
最后更新:2026-03-26