TypeScript基础进阶:掌握核心高级特性

155 阅读2分钟

一、泛型进阶:超越基础应用

泛型作为TypeScript的支柱特性,允许我们创建可重用的组件,同时保持类型安全。

泛型约束(Generic Constraints)

通过extends关键字约束泛型类型范围:

interface Lengthwise {
  length: number;
}

// 约束T必须包含length属性
function logLength<T extends Lengthwise>(arg: T): void {
  console.log(arg.length);
}

多类型参数与约束

function getProperty<T, K extends keyof T>(obj: T, key: K) {
  return obj[key];
}

const user = { name: 'Alice', age: 30 };
console.log(getProperty(user, 'age')); // 30
// console.log(getProperty(user, 'email'));  // 错误:email不存在的属性

条件类型(Conditional Types)

type NonNullable<T> = T extends null | undefined ? never : T;

type StringOrNumber = string | number | null;
type Valid = NonNullable<StringOrNumber>; // string | number

二、类型编程:构建动态类型系统

映射类型(Mapped Types)

通过索引签名转换已有类型:

type OptionsFlags<T> = {
  [P in keyof T]: boolean;
};

interface UserSettings {
  darkMode: boolean;
  notifications: boolean;
}

type FeatureFlags = OptionsFlags<UserSettings>;
// {
//   darkMode: boolean;
//   notifications: boolean;
// }

条件映射类型

type Getters<T> = {
  [P in keyof T as `get${Capitalize<string & P>}`]: () => T[P];
};

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

type UserGetters = Getters<User>;
// {
//   getName: () => string;
//   getAge: () => number;
// }

三、类型保护与推断:安全的类型操作

自定义类型守卫

function isNumberArray(value: unknown): value is number[] {
  return Array.isArray(value) && value.every(item => typeof item === 'number');
}

const unknownValue: unknown = [1, 2, 3];
if (isNumberArray(unknownValue)) {
  // 现在可安全使用数组方法
  unknownValue.push(4);
}

基于控制流的类型分析

function process(value: string | number) {
  if (typeof value === 'string') {
    // 此块中value自动推断为string
    return value.toUpperCase();
  } else {
    // 此块中value自动推断为number
    return value.toFixed(2);
  }
}

四、装饰器元编程:扩展类功能

类装饰器(Class Decorator)

function logClassCreation(constructor: Function) {
  console.log(`类已创建: ${constructor.name}`);
}

@logClassCreation
class ApiService {
  // 类实现
}

// 控制台输出:类已创建: ApiService

方法装饰器(Method Decorator)

function logMethod(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 {
  @logMethod
  add(a: number, b: number) {
    return a + b;
  }
}

const calc = new Calculator();
calc.add(2, 3); // 控制台输出:调用方法: add

五、类型工具库:内置工具类型解析

Partial/Required/Readonly

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

// 所有属性变为可选
type PartialUser = Partial<User>; 
// 所有属性变为必选
type RequiredUser = Required<User>; 
// 所有属性变为只读
type ReadonlyUser = Readonly<User>; 

Pick/Omit/Record

type PickUser = Pick<User, 'name'>;      // { name: string }
type OmitUser = Omit<User, 'age'>;        // { name: string }
type UserRecord = Record<'id', User>;     // { id: User }

六、高级技巧与实践

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

type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type ApiEndpoint = `/api/${string}`;

// 创建完整API路径类型
type ApiRoute = `${HttpMethod} ${ApiEndpoint}`;

const route: ApiRoute = 'GET /api/users';  // 有效
// const invalid: ApiRoute = 'POST /users';  // 无效

联合类型分配规则

type Distributive<T> = T extends any ? T[] : never;
type Distributed = Distributive<string | number>; // string[] | number[]

// 阻止分配
type NonDistributive<T> = [T] extends [any] ? T[] : never;
type NonDistributed = NonDistributive<string | number>; // (string | number)[]

结语:构建健壮的类型体系

掌握TypeScript高级特性后,您将能够:

  1. 创建高度可复用的泛型组件
  2. 实现编译时类型验证和转换
  3. 通过装饰器扩展类功能
  4. 构建复杂的类型约束系统
  5. 实现安全的运行时类型验证

通过实际项目的持续实践,您将能够构建出更健壮、更易维护的前端架构。请留意TypeScript每个新版本中引入的类型特性(如5.0引入的装饰器标准支持)。

进阶资源​: