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字面量类型:

字面量类型种类 #

  1. 字符串字面量:精确的字符串值
  2. 数字字面量:精确的数字值
  3. 布尔字面量:true或false
  4. 模板字面量:字符串模板组合

最佳实践 #

  1. 使用字面量类型定义精确的值集合
  2. 结合联合类型创建可辨识联合
  3. 使用as const获得字面量类型推断
  4. 使用模板字面量类型生成类型
  5. 根据场景选择字面量类型或枚举
最后更新:2026-03-26