概述

TypeScript是JavaScript的超集,添加了静态类型检查和现代JavaScript特性。它由Microsoft开发,旨在提高大型JavaScript应用的可维护性和开发效率。本指南将全面介绍TypeScript的核心概念和实际应用。

1. TypeScript基础

1.1 什么是TypeScript

TypeScript是JavaScript的类型化超集,编译成纯JavaScript。主要特性:

  • 静态类型检查:在编译时发现类型错误
  • 现代JavaScript特性:支持ES6+特性
  • 强大的工具支持:智能提示、重构、导航
  • 更好的代码组织:接口、类、模块等

1.2 安装和配置

# 全局安装TypeScript
npm install -g typescript

# 项目中安装
npm install --save-dev typescript

# 初始化TypeScript项目
npx tsc --init

# 编译TypeScript文件
tsc filename.ts

# 监听模式编译
tsc filename.ts --watch

# 使用ts-node直接运行
npm install -g ts-node
ts-node filename.ts

1.3 tsconfig.json配置

{
  "compilerOptions": {
    "target": "ES2020",              // 编译目标版本
    "module": "commonjs",            // 模块系统
    "lib": ["ES2020", "DOM"],        // 包含的库
    "outDir": "./dist",              // 输出目录
    "rootDir": "./src",              // 源码目录
    "strict": true,                  // 启用严格模式
    "esModuleInterop": true,         // ES模块互操作
    "skipLibCheck": true,            // 跳过库文件检查
    "forceConsistentCasingInFileNames": true,
    "declaration": true,             // 生成声明文件
    "sourceMap": true,               // 生成源码映射
    "removeComments": true,          // 移除注释
    "noImplicitAny": true,           // 禁止隐式any
    "strictNullChecks": true,         // 严格空值检查
    "strictFunctionTypes": true,     // 严格函数类型
    "noImplicitReturns": true,       // 函数必须有返回值
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "node",      // 模块解析策略
    "baseUrl": "./",                 // 基础路径
    "paths": {                       // 路径映射
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*"],            // 包含的文件
  "exclude": ["node_modules"]        // 排除的文件
}

2. 基础类型

2.1 基本类型

// 原始类型
let isDone: boolean = false;
let decimal: number = 6;
let color: string = "blue";
let list: number[] = [1, 2, 3];
let x: [string, number] = ["hello", 10]; // 元组

// 枚举
enum Color { Red, Green, Blue }
let c: Color = Color.Green;

enum Status {
  Pending = "pending",
  Approved = "approved",
  Rejected = "rejected"
}

// any类型(尽量避免使用)
let notSure: any = 4;
notSure = "maybe a string";
notSure = false;

// unknown类型(更安全的any)
let value: unknown = 4;
if (typeof value === "number") {
  console.log(value * 2); // 需要类型检查
}

// void类型
function warnUser(): void {
  console.log("This is a warning message");
}

// null和undefined
let u: undefined = undefined;
let n: null = null;

// never类型
function error(message: string): never {
  throw new Error(message);
}

// object类型
let obj: object = { name: "John" };
let person: { name: string; age: number } = {
  name: "John",
  age: 30
};

2.2 类型注解和推断

// 类型注解
let name: string = "John";
let age: number = 30;
let isActive: boolean = true;

// 类型推断
let inferred = "TypeScript"; // 推断为string
let number = 42; // 推断为number

// 函数类型注解
function greet(name: string): string {
  return `Hello, ${name}!`;
}

// 可选参数
function greetOptional(name?: string): string {
  return name ? `Hello, ${name}!` : "Hello, stranger!";
}

// 默认参数
function greetDefault(name: string = "Guest"): string {
  return `Hello, ${name}!`;
}

// 剩余参数
function sum(...numbers: number[]): number {
  return numbers.reduce((a, b) => a + b, 0);
}

3. 接口和类型别名

3.1 接口定义

// 基本接口
interface Person {
  name: string;
  age: number;
}

// 可选属性
interface User {
  id: number;
  name: string;
  email?: string;  // 可选属性
}

// 只读属性
interface Config {
  readonly apiUrl: string;
  readonly timeout: number;
}

// 函数类型接口
interface SearchFunc {
  (source: string, subString: string): boolean;
}

let mySearch: SearchFunc = function(source: string, subString: string): boolean {
  return source.search(subString) > -1;
};

// 索引签名
interface StringArray {
  [index: number]: string;
}

let myArray: StringArray = ["Bob", "Fred"];

// 混合类型接口
interface Counter {
  (start: number): string;
  interval: number;
  reset(): void;
}

function getCounter(): Counter {
  let counter = (function(start: number) { return start.toString(); }) as Counter;
  counter.interval = 123;
  counter.reset = function() { console.log("Reset"); };
  return counter;
}

3.2 接口继承

// 基本继承
interface Shape {
  color: string;
}

interface Square extends Shape {
  sideLength: number;
}

let square: Square = {
  color: "blue",
  sideLength: 10
};

// 多重继承
interface PenStroke {
  penWidth: number;
}

interface Circle extends Shape, PenStroke {
  radius: number;
}

// 接口实现
interface ClockInterface {
  currentTime: Date;
  setTime(d: Date): void;
}

class Clock implements ClockInterface {
  currentTime: Date = new Date();
  setTime(d: Date) {
    this.currentTime = d;
  }
  constructor(h: number, m: number) {}
}

3.3 类型别名

// 基本类型别名
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;

function getName(n: NameOrResolver): Name {
  if (typeof n === "string") {
    return n;
  } else {
    return n();
  }
}

// 对象类型别名
type Person = {
  name: string;
  age: number;
  address?: {
    street: string;
    city: string;
  };
};

// 联合类型
type Status = "pending" | "approved" | "rejected";
type ID = string | number;

// 泛型类型别名
type Container<T> = { value: T };
type Tree<T> = {
  value: T;
  left?: Tree<T>;
  right?: Tree<T>;
};

// 条件类型
type IsString<T> = T extends string ? true : false;
type Result = IsString<"hello">; // true

// 映射类型
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

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

// 使用示例
interface User {
  id: number;
  name: string;
  email: string;
}

type ReadonlyUser = Readonly<User>;
type PartialUser = Partial<User>;

4. 类

4.1 类的基本语法

// 基本类定义
class Greeter {
  // 属性
  greeting: string;

  // 构造函数
  constructor(message: string) {
    this.greeting = message;
  }

  // 方法
  greet(): string {
    return `Hello, ${this.greeting}`;
  }
}

let greeter = new Greeter("world");
console.log(greeter.greet());

// 继承
class Animal {
  name: string;

  constructor(theName: string) {
    this.name = theName;
  }

  move(distanceInMeters: number = 0) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
  }
}

class Dog extends Animal {
  constructor(name: string) {
    super(name); // 调用父类构造函数
  }

  move(distanceInMeters = 5) {
    console.log("Dog is running...");
    super.move(distanceInMeters);
  }

  bark() {
    console.log("Woof! Woof!");
  }
}

let dog = new Dog("Buddy");
dog.bark();
dog.move(10);

4.2 访问修饰符

class Person {
  public name: string;          // 公共属性(默认)
  private age: number;          // 私有属性
  protected gender: string;     // 受保护属性
  readonly id: number;          // 只读属性

  constructor(name: string, age: number, gender: string, id: number) {
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.id = id;
  }

  public getInfo(): string {
    return `${this.name} (${this.age})`;
  }

  private getAge(): number {
    return this.age;
  }

  protected getGender(): string {
    return this.gender;
  }
}

class Employee extends Person {
  private salary: number;

  constructor(name: string, age: number, gender: string, id: number, salary: number) {
    super(name, age, gender, id);
    this.salary = salary;
  }

  public getEmployeeInfo(): string {
    // 可以访问protected属性
    return `${this.name} - ${this.getGender()} - $${this.salary}`;
  }
}

// 参数属性(简化写法)
class Student {
  constructor(
    public firstName: string,
    private lastName: string,
    protected grade: number
  ) {}

  getFullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
}

4.3 静态属性和方法

class MathHelper {
  static PI: number = 3.14159;

  static calculateCircleArea(radius: number): number {
    return MathHelper.PI * radius * radius;
  }

  static isEven(num: number): boolean {
    return num % 2 === 0;
  }
}

// 使用静态成员
console.log(MathHelper.PI);
console.log(MathHelper.calculateCircleArea(5));
console.log(MathHelper.isEven(4));

class Counter {
  private static count: number = 0;

  constructor() {
    Counter.count++;
  }

  public static getCount(): number {
    return Counter.count;
  }
}

let c1 = new Counter();
let c2 = new Counter();
console.log(Counter.getCount()); // 2

4.4 抽象类

abstract class Animal {
  abstract name: string;

  abstract makeSound(): void; // 抽象方法

  move(): void { // 具体方法
    console.log(`${this.name} is moving`);
  }
}

class Cat extends Animal {
  name: string = "Cat";

  makeSound(): void {
    console.log("Meow!");
  }

  purr(): void {
    console.log("Purrr...");
  }
}

let cat = new Cat();
cat.makeSound();
cat.move();
cat.purr();

// 抽象类不能直接实例化
// let animal = new Animal(); // 错误

5. 泛型

5.1 泛型函数

// 基本泛型函数
function identity<T>(arg: T): T {
  return arg;
}

let output1 = identity<string>("myString");
let output2 = identity<number>(100);
let output3 = identity("myString"); // 类型推断

// 泛型约束
interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length); // 现在知道arg有length属性
  return arg;
}

loggingIdentity("hello"); // 可以
loggingIdentity([1, 2, 3]); // 可以
// loggingIdentity(3); // 错误,没有length属性

// 多个类型参数
function pair<T, U>(first: T, second: U): [T, U] {
  return [first, second];
}

let pairResult = pair<string, number>("hello", 42);

5.2 泛型类

class GenericNumber<T> {
  zeroValue: T;
  add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

class Stack<T> {
  private items: T[] = [];

  push(item: T): void {
    this.items.push(item);
  }

  pop(): T | undefined {
    return this.items.pop();
  }

  peek(): T | undefined {
    return this.items[this.items.length - 1];
  }

  isEmpty(): boolean {
    return this.items.length === 0;
  }

  size(): number {
    return this.items.length;
  }
}

let numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop()); // 2

let stringStack = new Stack<string>();
stringStack.push("hello");
stringStack.push("world");
console.log(stringStack.pop()); // "world"

5.3 泛型接口

interface GenericIdentityFn<T> {
  (arg: T): T;
}

let myIdentity: GenericIdentityFn<number> = identity;

interface Repository<T> {
  findById(id: number): Promise<T>;
  save(entity: T): Promise<T>;
  delete(id: number): Promise<void>;
}

class UserRepository implements Repository<User> {
  async findById(id: number): Promise<User> {
    // 实现查找用户逻辑
    return {} as User;
  }

  async save(user: User): Promise<User> {
    // 实现保存用户逻辑
    return user;
  }

  async delete(id: number): Promise<void> {
    // 实现删除用户逻辑
  }
}

6. 高级类型

6.1 联合类型和交叉类型

// 联合类型
type Status = "loading" | "success" | "error";

function handleStatus(status: Status): string {
  switch (status) {
    case "loading":
      return "Loading...";
    case "success":
      return "Success!";
    case "error":
      return "Error occurred";
  }
}

// 联合类型与类型守卫
interface Bird {
  fly(): void;
  layEggs(): void;
}

interface Fish {
  swim(): void;
  layEggs(): void;
}

type Pet = Bird | Fish;

function isBird(pet: Pet): pet is Bird {
  return (pet as Bird).fly !== undefined;
}

function handlePet(pet: Pet): void {
  if (isBird(pet)) {
    pet.fly();
  } else {
    pet.swim();
  }
}

// 交叉类型
interface Person {
  name: string;
  age: number;
}

interface Employee {
  id: number;
  department: string;
}

type EmployeePerson = Person & Employee;

let employee: EmployeePerson = {
  name: "John",
  age: 30,
  id: 123,
  department: "IT"
};

6.2 条件类型

// 基本条件类型
type IsString<T> = T extends string ? true : false;

type Test1 = IsString<string>; // true
type Test2 = IsString<number>; // false

// 条件类型与泛型
type NonNullable<T> = T extends null | undefined ? never : T;

type Test3 = NonNullable<string | null>; // string
type Test4 = NonNullable<number | undefined>; // number

// 映射条件类型
type ExtractType<T, U> = T extends U ? T : never;

type Test5 = ExtractType<string | number | boolean, string | number>; // string | number

// 推断条件类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

function greet(): string {
  return "Hello";
}

type GreetReturn = ReturnType<typeof greet>; // string

6.3 映射类型

// 基本映射类型
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

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

// 使用示例
interface User {
  id: number;
  name: string;
  email: string;
}

type ReadonlyUser = Readonly<User>;
type PartialUser = Partial<User>;

// 自定义映射类型
type Stringify<T> = {
  [K in keyof T]: string;
};

type StringifiedUser = Stringify<User>;

// 条件映射类型
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

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

7. 装饰器

7.1 类装饰器

// 基本类装饰器
function classDecorator<T extends { new(...args: any[]): {} }>(constructor: T) {
  return class extends constructor {
    newProperty = "new property";
    hello = "override";
  };
}

@classDecorator
class Greeter {
  property = "original property";
  hello = "original hello";
}

console.log(new Greeter().hello); // "override"

// 带参数的类装饰器
function entity(tableName: string) {
  return function<T extends { new(...args: any[]): {} }>(constructor: T) {
    return class extends constructor {
      tableName = tableName;
    };
  };
}

@entity("users")
class User {
  constructor(public name: string, public email: string) {}
}

console.log((new User("John", "john@example.com") as any).tableName); // "users"

7.2 方法装饰器

function log(target: any, propertyName: string, descriptor: PropertyDescriptor) {
  const method = descriptor.value;

  descriptor.value = function(...args: any[]) {
    console.log(`Calling ${propertyName} with args: ${JSON.stringify(args)}`);
    const result = method.apply(this, args);
    console.log(`${propertyName} returned: ${JSON.stringify(result)}`);
    return result;
  };
}

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

  @log
  multiply(a: number, b: number): number {
    return a * b;
  }
}

const calc = new Calculator();
calc.add(2, 3); // 输出日志
calc.multiply(4, 5); // 输出日志

7.3 属性装饰器

function validate(target: any, propertyName: string) {
  let value: string;

  const getter = () => value;

  const setter = (newValue: string) => {
    if (newValue.length < 3) {
      throw new Error(`${propertyName} must be at least 3 characters long`);
    }
    value = newValue;
  };

  Object.defineProperty(target, propertyName, {
    get: getter,
    set: setter,
    enumerable: true,
    configurable: true
  });
}

class Person {
  @validate
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

try {
  const person = new Person("Jo"); // 抛出错误
} catch (error) {
  console.error(error.message);
}

8. 模块和命名空间

8.1 ES模块

// math.ts
export const PI = 3.14159;

export function add(a: number, b: number): number {
  return a + b;
}

export function multiply(a: number, b: number): number {
  return a * b;
}

export class Calculator {
  divide(a: number, b: number): number {
    return a / b;
  }
}

// 默认导出
export default class MathUtils {
  static power(base: number, exponent: number): number {
    return Math.pow(base, exponent);
  }
}

// main.ts
import MathUtils, { PI, add, multiply, Calculator } from './math';

console.log(PI);
console.log(add(2, 3));
console.log(multiply(4, 5));

const calc = new Calculator();
console.log(calc.divide(10, 2));

console.log(MathUtils.power(2, 3));

// 重命名导入
import { add as sum } from './math';
console.log(sum(1, 2));

// 导入整个模块
import * as Math from './math';
console.log(Math.PI);
console.log(Math.add(1, 2));

8.2 命名空间

// shapes.ts
namespace Shapes {
  export interface Point {
    x: number;
    y: number;
  }

  export class Circle {
    constructor(public center: Point, public radius: number) {}

    area(): number {
      return Math.PI * this.radius * this.radius;
    }
  }

  export namespace Utils {
    export function distance(p1: Point, p2: Point): number {
      return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
    }
  }
}

// 使用命名空间
const center: Shapes.Point = { x: 0, y: 0 };
const circle = new Shapes.Circle(center, 5);
console.log(circle.area());

const p1: Shapes.Point = { x: 0, y: 0 };
const p2: Shapes.Point = { x: 3, y: 4 };
console.log(Shapes.Utils.distance(p1, p2));

// 嵌套命名空间
namespace MyApplication {
  export namespace Models {
    export interface User {
      id: number;
      name: string;
    }
  }

  export namespace Services {
    export class UserService {
      private users: Models.User[] = [];

      addUser(user: Models.User): void {
        this.users.push(user);
      }

      getUsers(): Models.User[] {
        return this.users;
      }
    }
  }
}

9. 异步编程

9.1 Promise和async/await

// 基本Promise
function fetchData(url: string): Promise<string> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url) {
        resolve(`Data from ${url}`);
      } else {
        reject(new Error("URL is required"));
      }
    }, 1000);
  });
}

// 使用Promise
fetchData("https://api.example.com")
  .then(data => console.log(data))
  .catch(error => console.error(error));

// async/await
async function fetchDataAsync(url: string): Promise<string> {
  try {
    const data = await fetchData(url);
    console.log(data);
    return data;
  } catch (error) {
    console.error("Error:", error);
    throw error;
  }
}

// 并行执行
async function fetchMultipleData(): Promise<string[]> {
  const urls = [
    "https://api.example.com/1",
    "https://api.example.com/2",
    "https://api.example.com/3"
  ];

  try {
    const results = await Promise.all(urls.map(url => fetchData(url)));
    return results;
  } catch (error) {
    console.error("Error fetching data:", error);
    throw error;
  }
}

// 竞争执行
async function fetchFirstAvailable(): Promise<string> {
  const urls = [
    "https://api.example.com/1",
    "https://api.example.com/2",
    "https://api.example.com/3"
  ];

  try {
    const result = await Promise.race(urls.map(url => fetchData(url)));
    return result;
  } catch (error) {
    console.error("All requests failed:", error);
    throw error;
  }
}

9.2 类型化异步操作

// 类型化的API响应
interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

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

// 类型化的API函数
async function fetchUser(id: number): Promise<ApiResponse<User>> {
  const response = await fetch(`/api/users/${id}`);
  
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  
  const data: ApiResponse<User> = await response.json();
  return data;
}

// 使用类型化API
async function displayUser(id: number): Promise<void> {
  try {
    const response = await fetchUser(id);
    const user = response.data;
    
    console.log(`User: ${user.name} (${user.email})`);
  } catch (error) {
    console.error("Failed to fetch user:", error);
  }
}

// 泛型API客户端
class ApiClient {
  private baseUrl: string;

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl;
  }

  async get<T>(endpoint: string): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseUrl}${endpoint}`);
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    return response.json();
  }

  async post<T>(endpoint: string, data: any): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });
    
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    
    return response.json();
  }
}

// 使用API客户端
const apiClient = new ApiClient('https://api.example.com');

async function createUser(userData: Omit<User, 'id'>): Promise<User> {
  const response = await apiClient.post<User>('/users', userData);
  return response.data;
}

10. 错误处理

10.1 类型化错误

// 自定义错误类
class CustomError extends Error {
  constructor(
    message: string,
    public code: string,
    public statusCode: number = 500
  ) {
    super(message);
    this.name = 'CustomError';
  }
}

class ValidationError extends CustomError {
  constructor(
    message: string,
    public field: string
  ) {
    super(message, 'VALIDATION_ERROR', 400);
    this.name = 'ValidationError';
  }
}

// 错误处理函数
function handleError(error: unknown): void {
  if (error instanceof ValidationError) {
    console.error(`Validation error in field ${error.field}: ${error.message}`);
  } else if (error instanceof CustomError) {
    console.error(`${error.code}: ${error.message}`);
  } else if (error instanceof Error) {
    console.error(`Unexpected error: ${error.message}`);
  } else {
    console.error('Unknown error occurred');
  }
}

// Result类型(函数式错误处理)
type Result<T, E = Error> = {
  success: true;
  data: T;
} | {
  success: false;
  error: E;
};

function safeParseInt(str: string): Result<number, Error> {
  const num = parseInt(str, 10);
  if (isNaN(num)) {
    return {
      success: false,
      error: new Error(`Cannot parse "${str}" as integer`)
    };
  }
  return {
    success: true,
    data: num
  };
}

// 使用Result类型
function processNumber(input: string): void {
  const result = safeParseInt(input);
  
  if (result.success) {
    console.log(`Parsed number: ${result.data}`);
  } else {
    console.error(`Error: ${result.error.message}`);
  }
}

10.2 异步错误处理

// 异步Result类型
type AsyncResult<T, E = Error> = Promise<Result<T, E>>;

async function safeFetch(url: string): AsyncResult<any> {
  try {
    const response = await fetch(url);
    
    if (!response.ok) {
      return {
        success: false,
        error: new Error(`HTTP error! status: ${response.status}`)
      };
    }
    
    const data = await response.json();
    return {
      success: true,
      data
    };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error : new Error('Unknown error')
    };
  }
}

// 使用异步Result
async function fetchUserData(userId: number): Promise<void> {
  const result = await safeFetch(`/api/users/${userId}`);
  
  if (result.success) {
    console.log('User data:', result.data);
  } else {
    console.error('Failed to fetch user:', result.error.message);
  }
}

// 错误边界装饰器
function withErrorHandling<T extends any[], R>(
  fn: (...args: T) => Promise<R>
) {
  return async (...args: T): Promise<Result<R>> => {
    try {
      const result = await fn(...args);
      return {
        success: true,
        data: result
      };
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error : new Error('Unknown error')
      };
    }
  };
}

// 使用错误边界装饰器
const safeFetchUser = withErrorHandling(async (id: number) => {
  const response = await fetch(`/api/users/${id}`);
  if (!response.ok) {
    throw new Error(`Failed to fetch user: ${response.status}`);
  }
  return response.json();
});

async function getUserData(id: number): Promise<void> {
  const result = await safeFetchUser(id);
  
  if (result.success) {
    console.log('User:', result.data);
  } else {
    console.error('Error:', result.error.message);
  }
}

11. 工具类型

11.1 内置工具类型

// Partial<T> - 将T的所有属性变为可选
interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type PartialTodo = Partial<Todo>;
// { title?: string; description?: string; completed?: boolean; }

// Required<T> - 将T的所有属性变为必需
type RequiredTodo = Required<Todo>;
// { title: string; description: string; completed: boolean; }

// Readonly<T> - 将T的所有属性变为只读
type ReadonlyTodo = Readonly<Todo>;
// { readonly title: string; readonly description: string; readonly completed: boolean; }

// Record<K, T> - 创建键为K类型,值为T类型的对象
type UserRoles = Record<string, boolean>;
// { [key: string]: boolean; }

// Pick<T, K> - 从T中选择一组属性K来创建类型
type TodoPreview = Pick<Todo, 'title' | 'completed'>;
// { title: string; completed: boolean; }

// Omit<T, K> - 从T中排除一组属性K来创建类型
type TodoWithoutDescription = Omit<Todo, 'description'>;
// { title: string; completed: boolean; }

// Exclude<T, U> - 从T中排除可分配给U的类型
type Primitive = string | number | boolean;
type NonStringPrimitive = Exclude<Primitive, string>;
// number | boolean

// Extract<T, U> - 从T中提取可分配给U的类型
type StringPrimitive = Extract<Primitive, string>;
// string

// NonNullable<T> - 从T中排除null和undefined
type NonNullableString = NonNullable<string | null | undefined>;
// string

// ReturnType<T> - 获取函数类型T的返回类型
type FunctionType = (a: number, b: number) => string;
type Return = ReturnType<FunctionType>;
// string

// Parameters<T> - 获取函数类型T的参数类型
type Params = Parameters<FunctionType>;
// [a: number, b: number]

// InstanceType<T> - 获取构造函数类型T的实例类型
class MyClass {
  constructor(public name: string) {}
}
type MyInstance = InstanceType<typeof MyClass>;
// MyClass

11.2 自定义工具类型

// 深度Partial
type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

interface Nested {
  a: {
    b: {
      c: string;
    };
  };
}

type PartialNested = DeepPartial<Nested>;
// { a?: { b?: { c?: string } } }

// 深度Readonly
type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};

// 条件类型:提取数组元素类型
type ArrayElement<T> = T extends (infer U)[] ? U : never;
type StringArray = string[];
type ElementType = ArrayElement<StringArray>; // string

// 条件类型:提取Promise解析值类型
type PromiseValue<T> = T extends Promise<infer U> ? U : never;
type StringPromise = Promise<string>;
type ResolvedType = PromiseValue<StringPromise>; // string

// 联合类型转交叉类型
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
  k: infer I
) => void
  ? I
  : never;

// 获取函数参数的最后一个类型
type LastParameter<T> = T extends (...args: infer A) => any
  ? A extends [...any, infer L]
    ? L
    : never
  : never;

type Func = (a: string, b: number, c: boolean) => void;
type LastParam = LastParameter<Func>; // boolean

// 创建可选的深度路径类型
type DeepPath<T, Path extends string> = Path extends keyof T
  ? T[Path]
  : Path extends `${infer Key}.${infer Rest}`
  ? Key extends keyof T
    ? DeepPath<T[Key], Rest>
    : never
  : never;

interface User {
  id: number;
  profile: {
    name: string;
    address: {
      city: string;
      country: string;
    };
  };
}

type CityType = DeepPath<User, 'profile.address.city'>; // string

12. 配置和构建

12.1 TypeScript配置最佳实践

{
  "compilerOptions": {
    // 基础配置
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    
    // 输出配置
    "outDir": "./dist",
    "rootDir": "./src",
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "removeComments": false,
    
    // 严格类型检查
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedIndexedAccess": true,
    
    // 额外检查
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitOverride": true,
    
    // 高级配置
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "incremental": true,
    "tsBuildInfoFile": "./dist/.tsbuildinfo"
  },
  "include": [
    "src/**/*",
    "types/**/*"
  ],
  "exclude": [
    "node_modules",
    "dist",
    "**/*.test.ts",
    "**/*.spec.ts"
  ]
}

12.2 构建工具集成

// package.json
{
  "name": "typescript-project",
  "version": "1.0.0",
  "scripts": {
    "build": "tsc",
    "build:watch": "tsc --watch",
    "dev": "ts-node src/index.ts",
    "start": "node dist/index.js",
    "clean": "rimraf dist",
    "lint": "eslint src/**/*.ts",
    "lint:fix": "eslint src/**/*.ts --fix",
    "test": "jest",
    "test:watch": "jest --watch"
  },
  "devDependencies": {
    "@types/node": "^18.0.0",
    "@types/jest": "^28.0.0",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "eslint": "^8.0.0",
    "jest": "^28.0.0",
    "rimraf": "^3.0.0",
    "ts-jest": "^28.0.0",
    "ts-node": "^10.0.0",
    "typescript": "^4.8.0"
  }
}

12.3 ESLint配置

// .eslintrc.json
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2020,
    "sourceType": "module",
    "project": "./tsconfig.json"
  },
  "plugins": ["@typescript-eslint"],
  "extends": [
    "eslint:recommended",
    "@typescript-eslint/recommended",
    "@typescript-eslint/recommended-requiring-type-checking"
  ],
  "rules": {
    "@typescript-eslint/no-unused-vars": "error",
    "@typescript-eslint/explicit-function-return-type": "warn",
    "@typescript-eslint/no-explicit-any": "warn",
    "@typescript-eslint/no-non-null-assertion": "warn",
    "@typescript-eslint/prefer-nullish-coalescing": "error",
    "@typescript-eslint/prefer-optional-chain": "error"
  }
}

13. 实际应用示例

13.1 类型安全的API客户端

// api-client.ts
interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

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

interface CreateUserRequest {
  name: string;
  email: string;
  password: string;
}

class ApiClient {
  private baseUrl: string;
  private headers: Record<string, string>;

  constructor(baseUrl: string, apiKey?: string) {
    this.baseUrl = baseUrl;
    this.headers = {
      'Content-Type': 'application/json',
      ...(apiKey && { 'Authorization': `Bearer ${apiKey}` })
    };
  }

  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<ApiResponse<T>> {
    const url = `${this.baseUrl}${endpoint}`;
    
    const response = await fetch(url, {
      ...options,
      headers: {
        ...this.headers,
        ...options.headers
      }
    });

    if (!response.ok) {
      throw new Error(`API request failed: ${response.status} ${response.statusText}`);
    }

    return response.json();
  }

  async get<T>(endpoint: string): Promise<T> {
    const response = await this.request<T>(endpoint);
    return response.data;
  }

  async post<T>(endpoint: string, data: any): Promise<T> {
    const response = await this.request<T>(endpoint, {
      method: 'POST',
      body: JSON.stringify(data)
    });
    return response.data;
  }

  async put<T>(endpoint: string, data: any): Promise<T> {
    const response = await this.request<T>(endpoint, {
      method: 'PUT',
      body: JSON.stringify(data)
    });
    return response.data;
  }

  async delete<T>(endpoint: string): Promise<T> {
    const response = await this.request<T>(endpoint, {
      method: 'DELETE'
    });
    return response.data;
  }
}

// 使用示例
class UserService {
  private client: ApiClient;

  constructor(baseUrl: string, apiKey?: string) {
    this.client = new ApiClient(baseUrl, apiKey);
  }

  async getUsers(): Promise<User[]> {
    return this.client.get<User[]>('/users');
  }

  async getUserById(id: number): Promise<User> {
    return this.client.get<User>(`/users/${id}`);
  }

  async createUser(userData: CreateUserRequest): Promise<User> {
    return this.client.post<User>('/users', userData);
  }

  async updateUser(id: number, userData: Partial<User>): Promise<User> {
    return this.client.put<User>(`/users/${id}`, userData);
  }

  async deleteUser(id: number): Promise<void> {
    return this.client.delete<void>(`/users/${id}`);
  }
}

13.2 状态管理示例

// store.ts
type State = {
  user: User | null;
  isLoading: boolean;
  error: string | null;
};

type Action =
  | { type: 'SET_LOADING'; payload: boolean }
  | { type: 'SET_USER'; payload: User }
  | { type: 'SET_ERROR'; payload: string }
  | { type: 'CLEAR_ERROR' };

class Store {
  private state: State;
  private listeners: Array<(state: State) => void> = [];

  constructor(initialState: State) {
    this.state = initialState;
  }

  getState(): State {
    return { ...this.state };
  }

  dispatch(action: Action): void {
    this.state = this.reducer(this.state, action);
    this.notify();
  }

  subscribe(listener: (state: State) => void): () => void {
    this.listeners.push(listener);
    return () => {
      const index = this.listeners.indexOf(listener);
      if (index > -1) {
        this.listeners.splice(index, 1);
      }
    };
  }

  private reducer(state: State, action: Action): State {
    switch (action.type) {
      case 'SET_LOADING':
        return { ...state, isLoading: action.payload };
      case 'SET_USER':
        return { ...state, user: action.payload, isLoading: false, error: null };
      case 'SET_ERROR':
        return { ...state, error: action.payload, isLoading: false };
      case 'CLEAR_ERROR':
        return { ...state, error: null };
      default:
        return state;
    }
  }

  private notify(): void {
    this.listeners.forEach(listener => listener(this.getState()));
  }
}

// 使用示例
const store = new Store({
  user: null,
  isLoading: false,
  error: null
});

// 订阅状态变化
const unsubscribe = store.subscribe((state) => {
  console.log('State changed:', state);
});

// 派发动作
store.dispatch({ type: 'SET_LOADING', payload: true });
store.dispatch({ type: 'SET_USER', payload: { id: 1, name: 'John', email: 'john@example.com', createdAt: '2023-01-01' } });

14. 最佳实践

14.1 代码组织

// types/index.ts
export interface User {
  id: number;
  name: string;
  email: string;
}

export interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

// utils/validation.ts
export interface ValidationRule<T> {
  validate: (value: T) => boolean;
  message: string;
}

export function validateField<T>(
  value: T,
  rules: ValidationRule<T>[]
): string[] {
  return rules
    .filter(rule => !rule.validate(value))
    .map(rule => rule.message);
}

// services/user-service.ts
import { User, ApiResponse } from '../types';

export class UserService {
  // 实现用户服务
}

// components/user-form.ts
import { User } from '../types';
import { validateField, ValidationRule } from '../utils/validation';

export class UserForm {
  private rules: ValidationRule<string>[] = [
    {
      validate: (value) => value.length >= 3,
      message: 'Name must be at least 3 characters'
    }
  ];

  validateName(name: string): string[] {
    return validateField(name, this.rules);
  }
}

14.2 性能优化

// 使用类型守卫优化运行时检查
function isString(value: unknown): value is string {
  return typeof value === 'string';
}

function processValue(value: unknown): string {
  if (isString(value)) {
    return value.toUpperCase();
  }
  return String(value);
}

// 使用泛型避免重复代码
interface Repository<T> {
  findById(id: number): Promise<T>;
  save(entity: T): Promise<T>;
  delete(id: number): Promise<void>;
}

class BaseRepository<T> implements Repository<T> {
  constructor(private apiUrl: string) {}

  async findById(id: number): Promise<T> {
    const response = await fetch(`${this.apiUrl}/${id}`);
    return response.json();
  }

  async save(entity: T): Promise<T> {
    const response = await fetch(this.apiUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(entity)
    });
    return response.json();
  }

  async delete(id: number): Promise<void> {
    await fetch(`${this.apiUrl}/${id}`, { method: 'DELETE' });
  }
}

// 使用记忆化优化计算密集型操作
function memoize<T extends (...args: any[]) => any>(fn: T): T {
  const cache = new Map();
  
  return ((...args: any[]) => {
    const key = JSON.stringify(args);
    
    if (cache.has(key)) {
      return cache.get(key);
    }
    
    const result = fn(...args);
    cache.set(key, result);
    return result;
  }) as T;
}

const expensiveCalculation = memoize((n: number): number => {
  console.log('Performing expensive calculation...');
  return n * n;
});

15. 总结

TypeScript为JavaScript开发带来了强大的类型系统和现代编程特性。通过掌握以下核心概念,您可以构建更安全、更可维护的应用程序:

核心优势

  • 类型安全:在编译时发现错误,减少运行时问题
  • 更好的工具支持:智能提示、重构、代码导航
  • 代码可读性:明确的类型注解提高代码可理解性
  • 大型项目支持:模块化、接口、命名空间等特性

关键概念

  • 基础类型系统:原始类型、接口、类、泛型
  • 高级类型:联合类型、交叉类型、条件类型、映射类型
  • 异步编程:类型化的Promise和async/await
  • 模块系统:ES模块和命名空间
  • 工具类型:内置和自定义工具类型

最佳实践

  • 启用严格模式:使用strict: true获得最佳类型检查
  • 避免any类型:使用unknown或具体类型替代
  • 使用接口定义契约:明确数据结构和API契约
  • 合理使用泛型:提高代码复用性和类型安全
  • 配置适当的构建工具:ESLint、Prettier、Jest等

TypeScript的学习曲线相对平缓,但深度很大。建议从基础开始,逐步掌握高级特性,并在实际项目中不断实践和优化。通过持续学习和应用,您将能够充分发挥TypeScript的强大功能,构建高质量的JavaScript应用程序。