Skip to content

TypeScript的高级用法

约 1131 字大约 4 分钟

TypeScript

2025-09-12

TypeScript 作为 JavaScript 的超集,引入了许多强大的类型系统特性,本文将详细介绍 TypeScript 的各种高级用法。

1. 类型别名 vs 接口

类型别名 (Type Aliases)

使用 type 关键字创建新名称来引用一个类型:

type UserID = string | number;
type User = {
  id: UserID;
  name: string;
  email: string;
};

接口 (Interfaces)

使用 interface 关键字定义对象形状:

interface User {
  id: string | number;
  name: string;
  email: string;
}

主要区别

  • 接口可扩展(使用 extends),类型别名使用 & 交叉类型
  • 接口支持声明合并(同名接口自动合并)
  • 类型别名可以表示原始类型、联合类型、元组等

2. 实用工具类型

TypeScript 提供了一系列内置工具类型来简化常见类型转换:

Partial<T>

使类型 T 的所有属性变为可选:

interface User {
  name: string;
  age: number;
}

type PartialUser = Partial<User>;
// 等价于 { name?: string; age?: number; }

Required<T>

使类型 T 的所有属性变为必需:

interface User {
  name?: string;
  age?: number;
}

type RequiredUser = Required<User>;
// 等价于 { name: string; age: number; }

Readonly<T>

使类型 T 的所有属性变为只读:

interface User {
  name: string;
  age: number;
}

type ReadonlyUser = Readonly<User>;
// 等价于 { readonly name: string; readonly age: number; }

Pick<T, K>

从类型 T 中选择一组属性 K

interface User {
  name: string;
  age: number;
  email: string;
}

type UserBasicInfo = Pick<User, 'name' | 'email'>;
// 等价于 { name: string; email: string; }

Omit<T, K>

从类型 T 中排除一组属性 K

interface User {
  name: string;
  age: number;
  email: string;
}

type UserWithoutEmail = Omit<User, 'email'>;
// 等价于 { name: string; age: number; }

Record<K, T>

构造一个对象类型,其属性键为 K,属性值为 T

type UserRoles = Record<string, boolean>;
// 等价于 { [key: string]: boolean; }

Exclude<T, U>

从类型 T 中排除那些可以赋值给 U 的类型:

type T = Exclude<'a' | 'b' | 'c', 'a'>;
// 结果为 'b' | 'c'

Extract<T, U>

从类型 T 中提取那些可以赋值给 U 的类型:

type T = Extract<'a' | 'b' | 'c' | 1, string>;
// 结果为 'a' | 'b' | 'c'

NonNullable<T>

从类型 T 中排除 nullundefined

type T = NonNullable<string | null | undefined>;
// 结果为 string

ReturnType<T>

获取函数类型 T 的返回值类型:

type T = ReturnType<() => string>;
// 结果为 string

Parameters<T>

获取函数类型 T 的参数类型:

type T = Parameters<(a: string, b: number) => void>;
// 结果为 [a: string, b: number]

3. 高级类型特性

联合类型 (Union Types)

表示一个值可以是几种类型之一:

type ID = string | number;
type Status = 'active' | 'inactive' | 'pending';

交叉类型 (Intersection Types)

将多个类型合并为一个类型:

interface Person {
  name: string;
}

interface Employee {
  employeeId: number;
}

type Staff = Person & Employee;
// 必须同时有 name 和 employeeId

类型守卫 (Type Guards)

在运行时检查类型,帮助 TypeScript 缩小类型范围:

function isString(value: any): value is string {
  return typeof value === 'string';
}

if (isString(input)) {
  // 这里 TypeScript 知道 input 是 string 类型
  console.log(input.toUpperCase());
}

索引签名 (Index Signatures)

定义对象中未知属性的类型:

interface StringDictionary {
  [key: string]: string;
}

const dict: StringDictionary = {
  name: "John",
  email: "john@example.com"
};

映射类型 (Mapped Types)

基于旧类型创建新类型:

type Optional<T> = {
  [P in keyof T]?: T[P];
};

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

条件类型 (Conditional Types)

根据条件选择类型:

type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>; // true
type B = IsString<number>; // false

模板字面量类型 (Template Literal Types)

基于字符串模板创建类型:

type Event = 'click' | 'scroll';
type Handler = `on${Capitalize<Event>}`;
// 结果为 'onClick' | 'onScroll'

4. 枚举 (Enums)

TypeScript 扩展了 JavaScript 的枚举功能:

// 数字枚举
enum Direction {
  Up = 1,
  Down,
  Left,
  Right
}

// 字符串枚举
enum FileAccess {
  Read = "READ",
  Write = "WRITE"
}

// 常量枚举(编译时被完全移除)
const enum Colors {
  Red,
  Green,
  Blue
}

5. 泛型约束

使用 extends 关键字约束泛型参数:

interface HasLength {
  length: number;
}

function logLength<T extends HasLength>(arg: T): void {
  console.log(arg.length);
}

// 只能传递有 length 属性的参数
logLength("hello"); // 5
logLength([1, 2, 3]); // 3

6. 命名空间 (Namespaces)

TypeScript 中的命名空间帮助组织代码,避免全局污染:

namespace Utilities {
  export function formatDate(date: Date): string {
    return date.toISOString();
  }
  
  export function generateId(): string {
    return Math.random().toString(36).substr(2, 9);
  }
}

// 使用命名空间中的函数
Utilities.formatDate(new Date());

7. 声明文件 (.d.ts)

为 JavaScript 库提供类型信息:

// global.d.ts
declare module 'my-library' {
  export function doSomething(): void;
  export const value: number;
}

// 使用声明
import { doSomething } from 'my-library';

8. 装饰器 (Decorators)

TypeScript 支持装饰器(实验性特性),用于修改类、方法、属性等:

function log(target: any, key: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;
  
  descriptor.value = function(...args: any[]) {
    console.log(`调用方法: ${key}`);
    return originalMethod.apply(this, args);
  };
  
  return descriptor;
}

class Calculator {
  @log
  add(a: number, b: number): number {
    return a + b;
  }
}