现代 JavaScript 特性:TypeScript 深度解析与实践

引言

TypeScript作为JavaScript的超集,为现代前端开发带来了强大的类型系统和面向对象编程能力。它不仅在编译时提供类型检查,还支持ECMAScript的最新特性,极大地提高了代码的可维护性和开发体验。本文将深入探讨TypeScript的核心特性,包括类型检查、接口泛型、装饰器等底层实现原理,并补充类型推断、高级类型、工程化实践等关键内容,通过完整代码示例展示TypeScript在真实项目中的应用价值。

一、类型检查的简单实现

运行时类型检查的基础

TypeScript在编译时进行类型检查,但理解其背后的原理有助于我们实现运行时类型检查。

javascript 复制代码
// 1.1 基础类型检查器
class TypeChecker {
  static isString(value) {
    return typeof value === "string";
  }

  static isNumber(value) {
    return typeof value === "number" && !isNaN(value);
  }

  static isBoolean(value) {
    return typeof value === "boolean";
  }

  static isArray(value) {
    return Array.isArray(value);
  }

  static isObject(value) {
    return value !== null && typeof value === "object" && !Array.isArray(value);
  }

  static isFunction(value) {
    return typeof value === "function";
  }

  static isNull(value) {
    return value === null;
  }

  static isUndefined(value) {
    return typeof value === "undefined";
  }

  // 复合类型检查
  static isType(value, expectedType) {
    switch (expectedType) {
      case "string":
        return this.isString(value);
      case "number":
        return this.isNumber(value);
      case "boolean":
        return this.isBoolean(value);
      case "array":
        return this.isArray(value);
      case "object":
        return this.isObject(value);
      case "function":
        return this.isFunction(value);
      case "null":
        return this.isNull(value);
      case "undefined":
        return this.isUndefined(value);
      default:
        throw new Error(`Unsupported type: ${expectedType}`);
    }
  }
}

console.log(TypeChecker.isString("hello")); // true
console.log(TypeChecker.isNumber(42)); // true
console.log(TypeChecker.isType([1, 2, 3], "array")); // true

// 1.2 增强的类型检查器
class EnhancedTypeChecked {
  static types = {
    string: (value) => typeof value === "string",
    number: (value) => typeof value === "number" && !isNaN(value),
    boolean: (value) => typeof value === "boolean",
    array: (value) => Array.isArray(value),
    object: (value) =>
      value !== null && typeof value === "object" && !Array.isArray(value),
    function: (value) => typeof value === "function",
    null: (value) => value === null,
    undefined: (value) => typeof value === "undefined",
    // 自定义类型
    email: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value),
    uuid: (value) =>
      /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
        value
      ),
    date: (value) => value instanceof Date,
    // 联合类型
    union: (value, types) => types.some((type) => this.check(value, type)),
    // 字面量类型
    literal: (value, expected) => vaue === expected,
  };

  static check(value, type) {
    if (typeof type === "string") {
      const checker = this.types[type];
      return checker ? checker(value) : false;
    }
    if (typeof type === "object" && type.type) {
      if (type.type === "union") {
        return this.types.union(value, type.types);
      }
      if (type.type === "literal") {
        return this.types.literal(value, type.value);
      }
    }

    return false;
  }

  static validate(value, schema) {
    if (typeof schema === "string") {
      return this.check(value, schema);
    }

    if (Array.isArray(schema)) {
      // 数组类型
      if (!this.check(value, "array")) {
        return false;
      }
      const [itemType] = schema;
      return value.every((item) => this.validate(item, itemType));
    }

    if (typeof schema === "object" && !Array.isArray(schema)) {
      // 对象类型
      if (!this.check(value, "object")) return false;

      for (const [key, propSchema] of Object.entries(schema)) {
        if (!this.validate(value[key], propSchema)) {
          return false;
        }
      }

      return true;
    }
    return false;
  }
}

// 使用示例
const schema = {
  name: "string",
  age: "number",
  email: "email",
  tags: ["string"],
  address: {
    street: "string",
    city: "string",
  },
};

const data = {
  name: "John",
  age: 30,
  email: "john@example.com",
  tags: ["developer", "typescript"],
  address: {
    street: "123 Main St",
    city: "New York",
  },
};

console.log(EnhancedTypeChecked.validate(data, schema)); // true

// 1.3 编译时类型检查模拟
function createTypeSafeProxy(target, schema) {
  return new Proxy(target, {
    set(obj, prop, value) {
      if (schema[prop]) {
        const isValid = EnhancedTypeChecked.validate(value, schema[prop]);
        if (!isValid) {
          throw new TypeError(
            `Invalid type for property ${prop}. Expected ${JSON.stringify(
              schema[prop]
            )}, got ${typeof value}`
          );
        }
      }
      obj[prop] = value;
      return true;
    },
    get(obj, prop) {
      return obj[prop];
    },
  });
}

const userSchema = {
  name: "string",
  age: "number",
  active: "boolean",
};

const user = createTypeSafeProxy({}, userSchema);

try {
  user.name = "Alice"; // 成功
  user.age = "25"; // Invalid type for property age. Expected "number", got string
} catch (error) {
  console.error(error.message);
}
TypeScript编译器模拟
javascript 复制代码
class SimpleTypeScriptCompiler {
  constructor() {
    this.typeRegistry = new Map();
    this.errors = [];
  }

  // 解析类型注释
  parseTypeAnnotation(code) {
    const typeRegex = /:\s*([^{}\[\]]+|\{[^}]+\}|\[[^\]]+\])/g;
    const matches = [];
    let match;

    while ((match = typeRegex.exec(code)) !== null) {
      matches.push(match[1].trim());
    }

    return matches;
  }

  // 提取接口定义
  extractInterface(code) {
    const interfaceRegex = /interface\s+(\w+)\s*\{([^}]+)\}/g;
    const interfaces = new Map();
    let match;

    while ((match = interfaceRegex.exec(code)) !== null) {
      const [, name, body] = match;
      const properties = {};

      body.split(";").forEach((line) => {
        const propMatch = line.trim().match(/(\w+)\s*:\s*([^;]+)/);
        if (propMatch) {
          const [, propName, propType] = propMatch;
          properties[propName] = propType.trim();
        }
      });

      interfaces.set(name, properties);
    }

    return interfaces;
  }

  // 检查函数类型
  checkFunctionTypes(code, interfaces) {
    const functionRegex =
      /function\s+(\w+)\(([^)]*)\)\s*(?::\s*([^{]+))?\s*\{/g;
    const errors = [];
    let match;

    while ((match = functionRegex.exec(code)) !== null) {
      const [, functionName, params, returnType] = match;

      // 检查参数类型
      if (params) {
        params.split(",").forEach((param) => {
          const paramMatch = param.match(/(\w+)\s*:\s*(\w+)/);
          if (paramMatch) {
            const [, paramName, paramType] = paramMatch;
            // 这里可以添加实际类型检查逻辑
          }
        });
      }

      // 这里可以添加返回值类型检查逻辑
    }

    return errors;
  }

  // 编译TypeScript代码
  compile(code) {
    this.errors = [];

    // 提取接口
    const interfaces = this.extractInterface(code);

    // 检查类型
    const typeErrors = this.checkFunctionTypes(code, interfaces);
    this.errors.push(...typeErrors);

    // 移除类型注释, 生成JavaScript代码
    let jsCode = code
      .replace(/:\s*([^{}\[\]]+|\{[^}]+\}|\[[^\]]+\])/g, "") // 移除参数和变量类型
      .replace(/interface\s+\w+\s*\{[^}]+\}/g, "") // 移除接口定义
      .replace(/\s*\/\/.*$/gm, "") // 移除注释
      .trim();

    return {
      jsCode,
      errors: this.errors,
      interfaces: Array.from(interfaces.entries()),
    };
  }
}

// 使用示例
const tsCode = `
interface User {
  name: string;
  age: number;
}

function greet(user: User): string {
  return "Hello, " + user.name;
}

const john: User = { name: "John", age: 30 };
console.log(greet(john));
`;

const compiler = new SimpleTypeScriptCompiler();
const result = compiler.compile(tsCode);

console.log("生成的JavaScript代码:");
console.log(result.jsCode);
console.log("提取的接口:", result.interfaces);
console.log("类型错误:", result.errors);

二、接口和泛型的模拟

接口的实现与模拟
javascript 复制代码
// 2.1 接口检查器
class InterfaceChecker {
  static interfaces = new Map();
  
  // 定义接口
  static defineInterface(name, structure) {
    this.interfaces.set(name, structure);
  }
  
  // 检查对象是否实现接口
  static implements(obj, interfaceName) {
    const interfaceDef = this.interfaces.get(interfaceName);
    if (!interfaceDef) {
      throw new Error(`接口 ${interfaceName} 未定义`);
    }
    
    // 检查所有必需属性
    for (const [prop, type] of Object.entries(interfaceDef.required || {})) {
      if (!(prop in obj)) {
        return false;
      }
      if (type && !this.checkType(obj[prop], type)) {
        return false;
      }
    }
    
    // 检查可选属性类型(如果存在)
    for (const [prop, type] of Object.entries(interfaceDef.optional || {})) {
      if (prop in obj && type && !this.checkType(obj[prop], type)) {
        return false;
      }
    }
    
    // 检查方法
    for (const method of interfaceDef.methods || []) {
      if (!(method in obj) || typeof obj[method] !== 'function') {
        return false;
      }
    }
    
    return true;
  }
  
  // 类型检查
  static checkType(value, type) {
    if (typeof type === 'string') {
      switch (type) {
        case 'string': return typeof value === 'string';
        case 'number': return typeof value === 'number' && !isNaN(value);
        case 'boolean': return typeof value === 'boolean';
        case 'object': return value !== null && typeof value === 'object';
        default: return true;
      }
    }
    
    if (Array.isArray(type)) {
      return Array.isArray(value) && value.every(item => this.checkType(item, type[0]));
    }
    
    return true;
  }
  
  // 创建实现接口的类
  static createClass(interfaceName, implementation) {
    const interfaceDef = this.interfaces.get(interfaceName);
    if (!interfaceDef) {
      throw new Error(`接口 ${interfaceName} 未定义`);
    }
    
    // 创建类
    const DynamicClass = class {
      constructor(...args) {
        if (implementation.constructor) {
          implementation.constructor.apply(this, args);
        }
        
        // 验证实例是否符合接口
        if (!this.implements(interfaceName)) {
          throw new Error(`类未正确实现接口 ${interfaceName}`);
        }
      }
      
      implements(interfaceName) {
        return InterfaceChecker.implements(this, interfaceName);
      }
    };
    
    // 添加接口要求的方法和属性
    for (const [prop, descriptor] of Object.entries(implementation)) {
      if (prop !== 'constructor') {
        Object.defineProperty(DynamicClass.prototype, prop, descriptor);
      }
    }
    
    return DynamicClass;
  }
}

// 定义接口
InterfaceChecker.defineInterface('Serializable', {
  required: {
    toJSON: 'function',
    fromJSON: 'function'
  }
});

InterfaceChecker.defineInterface('User', {
  required: {
    id: 'number',
    name: 'string'
  },
  optional: {
    email: 'string',
    age: 'number'
  },
  methods: ['save', 'delete']
});

// 2.2 使用接口
const UserClass = InterfaceChecker.createClass('User', {
  constructor: function(id, name) {
    this.id = id;
    this.name = name;
  },
  
  save: {
    value: function() {
      console.log(`保存用户 ${this.name}`);
      return true;
    }
  },
  
  delete: {
    value: function() {
      console.log(`删除用户 ${this.name}`);
      return true;
    }
  },
  
  toJSON: {
    value: function() {
      return {
        id: this.id,
        name: this.name
      };
    }
  }
});

const user = new UserClass(1, 'Alice');
console.log(user.implements('User')); // true
console.log(user.implements('Serializable')); // false

// 2.3 运行时接口验证装饰器
function implementsInterface(interfaceName) {
  return function(target) {
    const originalConstructor = target;
    
    // 返回新的构造函数
    const newConstructor = function(...args) {
      const instance = new originalConstructor(...args);
      
      if (!InterfaceChecker.implements(instance, interfaceName)) {
        throw new Error(`类 ${target.name} 未实现接口 ${interfaceName}`);
      }
      
      return instance;
    };
    
    // 复制原型链
    newConstructor.prototype = originalConstructor.prototype;
    
    return newConstructor;
  };
}

// 使用装饰器
@interface('User')
class AdminUser {
  constructor(id, name) {
    this.id = id;
    this.name = name;
  }
  
  save() {
    console.log('保存管理员');
  }
  
  delete() {
    console.log('删除管理员');
  }
}

try {
  const admin = new AdminUser(1, 'Admin');
  console.log('AdminUser创建成功');
} catch (error) {
  console.error(error.message);
}
泛型的实现与模拟
javascript 复制代码
// 2.4 泛型容器类
class GenericContainer {
  constructor(value) {
    this._value = value;
  }
  
  get value() {
    return this._value;
  }
  
  set value(newValue) {
    this._value = newValue;
  }
  
  // 泛型方法:转换值类型
  map(transformer) {
    return new GenericContainer(transformer(this._value));
  }
  
  // 检查类型(运行时)
  checkType(expectedType) {
    return typeof this._value === expectedType;
  }
}

// 使用示例
const numberContainer = new GenericContainer(42);
console.log(numberContainer.value); // 42
console.log(numberContainer.checkType('number')); // true

const stringContainer = numberContainer.map(n => `数字: ${n}`);
console.log(stringContainer.value); // "数字: 42"
console.log(stringContainer.checkType('string')); // true

// 2.5 泛型函数工厂
function createGenericFunction(typeCheck) {
  return {
    // 泛型身份函数
    identity: function(value) {
      if (typeCheck && !typeCheck(value)) {
        throw new TypeError('类型不匹配');
      }
      return value;
    },
    
    // 泛型数组操作
    filterArray: function(arr, predicate) {
      if (!Array.isArray(arr)) {
        throw new TypeError('第一个参数必须是数组');
      }
      return arr.filter(predicate);
    },
    
    // 泛型映射
    mapArray: function(arr, mapper) {
      if (!Array.isArray(arr)) {
        throw new TypeError('第一个参数必须是数组');
      }
      return arr.map(mapper);
    }
  };
}

// 创建特定类型的泛型函数
const numberFunctions = createGenericFunction(val => typeof val === 'number');
const stringFunctions = createGenericFunction(val => typeof val === 'string');

console.log(numberFunctions.identity(123)); // 123
console.log(stringFunctions.identity('hello')); // "hello"

// 2.6 泛型约束模拟
class GenericValidator {
  static validate(value, constraints) {
    // 类型约束
    if (constraints.type && typeof value !== constraints.type) {
      return false;
    }
    
    // 最小/最大值约束
    if (constraints.min !== undefined && value < constraints.min) {
      return false;
    }
    
    if (constraints.max !== undefined && value > constraints.max) {
      return false;
    }
    
    // 长度约束
    if (constraints.minLength !== undefined && value.length < constraints.minLength) {
      return false;
    }
    
    if (constraints.maxLength !== undefined && value.length > constraints.maxLength) {
      return false;
    }
    
    // 自定义验证函数
    if (constraints.validator && !constraints.validator(value)) {
      return false;
    }
    
    return true;
  }
  
  // 创建受约束的泛型类
  static createConstrainedClass(constraints) {
    return class ConstrainedContainer {
      constructor(value) {
        if (!GenericValidator.validate(value, constraints)) {
          throw new Error('值不符合约束条件');
        }
        this._value = value;
      }
      
      get value() {
        return this._value;
      }
      
      set value(newValue) {
        if (!GenericValidator.validate(newValue, constraints)) {
          throw new Error('新值不符合约束条件');
        }
        this._value = newValue;
      }
    };
  }
}

// 使用泛型约束
const NumberContainer = GenericValidator.createConstrainedClass({
  type: 'number',
  min: 0,
  max: 100
});

const StringContainer = GenericValidator.createConstrainedClass({
  type: 'string',
  minLength: 2,
  maxLength: 50
});

try {
  const numContainer = new NumberContainer(50); // 成功
  console.log(numContainer.value); // 50
  
  const strContainer = new StringContainer('Hello'); // 成功
  console.log(strContainer.value); // "Hello"
  
  // numContainer.value = 150; // 抛出错误
} catch (error) {
  console.error(error.message);
}

// 2.7 泛型工具类型模拟
class GenericUtils {
  // 模拟 Partial<T>
  static partial(obj) {
    const result = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        result[key] = obj[key];
      }
    }
    return result;
  }
  
  // 模拟 Readonly<T>
  static readonly(obj) {
    const result = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        Object.defineProperty(result, key, {
          value: obj[key],
          writable: false,
          enumerable: true,
          configurable: false
        });
      }
    }
    return Object.freeze(result);
  }
  
  // 模拟 Pick<T, K>
  static pick(obj, keys) {
    const result = {};
    keys.forEach(key => {
      if (key in obj) {
        result[key] = obj[key];
      }
    });
    return result;
  }
  
  // 模拟 Omit<T, K>
  static omit(obj, keys) {
    const result = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key) && !keys.includes(key)) {
        result[key] = obj[key];
      }
    }
    return result;
  }
  
  // 模拟 Record<K, T>
  static record(keys, valueCreator) {
    const result = {};
    keys.forEach(key => {
      result[key] = valueCreator(key);
    });
    return result;
  }
}

// 使用泛型工具
const user = {
  id: 1,
  name: 'John',
  email: 'john@example.com',
  age: 30
};

console.log(GenericUtils.pick(user, ['id', 'name'])); // { id: 1, name: 'John' }
console.log(GenericUtils.omit(user, ['email', 'age'])); // { id: 1, name: 'John' }

const readonlyUser = GenericUtils.readonly(user);
// readonlyUser.name = 'Bob'; // 在严格模式下会抛出错误

三、装饰器的实现原理

装饰器基础实现
javascript 复制代码
// 3.1 基础装饰器工厂
function createDecorator(decoratorFunc) {
  return function(...args) {
    // 类装饰器
    if (args.length === 1 && typeof args[0] === 'function') {
      const targetClass = args[0];
      return decoratorFunc(targetClass) || targetClass;
    }
    
    // 方法装饰器
    if (args.length === 3 && typeof args[2] === 'object') {
      const [target, property, descriptor] = args;
      return decoratorFunc(target, property, descriptor) || descriptor;
    }
    
    // 属性装饰器
    if (args.length === 2 && typeof args[1] === 'string') {
      const [target, property] = args;
      decoratorFunc(target, property);
      return;
    }
    
    // 参数装饰器
    if (args.length === 3 && typeof args[2] === 'number') {
      const [target, property, parameterIndex] = args;
      decoratorFunc(target, property, parameterIndex);
      return;
    }
    
    return decoratorFunc(...args);
  };
}

// 3.2 类装饰器
function classDecorator(logMessage) {
  return createDecorator((targetClass) => {
    // 保存原始构造函数
    const originalConstructor = targetClass;
    
    // 创建新的构造函数
    const newConstructor = function(...args) {
      console.log(`${logMessage}: 创建 ${originalConstructor.name} 实例`);
      const instance = new originalConstructor(...args);
      
      // 可以在这里修改实例
      if (logMessage.includes('sealed')) {
        Object.seal(instance);
      }
      
      return instance;
    };
    
    // 复制原型链
    newConstructor.prototype = originalConstructor.prototype;
    
    // 复制静态属性
    Object.setPrototypeOf(newConstructor, originalConstructor);
    
    return newConstructor;
  });
}

// 3.3 方法装饰器
function methodDecorator(options = {}) {
  return createDecorator((target, property, descriptor) => {
    const originalMethod = descriptor.value;
    
    descriptor.value = function(...args) {
      // 前置处理
      if (options.log) {
        console.log(`调用方法: ${property}, 参数:`, args);
      }
      
      if (options.measureTime) {
        console.time(`方法 ${property} 执行时间`);
      }
      
      // 执行原始方法
      const result = originalMethod.apply(this, args);
      
      // 后置处理
      if (options.measureTime) {
        console.timeEnd(`方法 ${property} 执行时间`);
      }
      
      if (options.log) {
        console.log(`方法 ${property} 返回:`, result);
      }
      
      return result;
    };
    
    return descriptor;
  });
}

// 3.4 属性装饰器
function propertyDecorator(defaultValue) {
  return createDecorator((target, property) => {
    // 创建私有属性名称
    const privateProp = `_${property}`;
    
    // 定义getter和setter
    Object.defineProperty(target, property, {
      get() {
        return this[privateProp] !== undefined ? this[privateProp] : defaultValue;
      },
      set(value) {
        this[privateProp] = value;
      },
      enumerable: true,
      configurable: true
    });
  });
}

// 3.5 参数装饰器
function parameterDecorator(validator) {
  return createDecorator((target, property, parameterIndex) => {
    // 获取方法的参数验证元数据
    if (!target.__parameterValidations) {
      target.__parameterValidations = new Map();
    }
    
    const key = `${property}_${parameterIndex}`;
    target.__parameterValidations.set(key, validator);
    
    // 重写方法以添加参数验证
    const originalMethod = target[property];
    
    target[property] = function(...args) {
      // 验证参数
      const validator = target.__parameterValidations.get(`${property}_${parameterIndex}`);
      if (validator && !validator(args[parameterIndex])) {
        throw new Error(`参数 ${parameterIndex} 验证失败`);
      }
      
      return originalMethod.apply(this, args);
    };
  });
}

// 使用示例
@classDecorator('自动日志记录 - sealed')
class UserService {
  @propertyDecorator('guest')
  role;
  
  constructor(name) {
    this.name = name;
  }
  
  @methodDecorator({ log: true, measureTime: true })
  greet(@parameterDecorator(val => typeof val === 'string') message) {
    return `${this.name} 说: ${message}`;
  }
  
  @methodDecorator({ log: true })
  setRole(@parameterDecorator(role => ['admin', 'user', 'guest'].includes(role)) newRole) {
    this.role = newRole;
  }
}

const service = new UserService('Alice');
console.log(service.role); // "guest" (默认值)
service.setRole('admin');
console.log(service.greet('你好!')); // 输出日志和结果
高级装饰器模式
javascript 复制代码
// 3.6 依赖注入装饰器
class DependencyContainer {
  static dependencies = new Map();
  
  static register(token, implementation) {
    this.dependencies.set(token, implementation);
  }
  
  static resolve(token) {
    const dependency = this.dependencies.get(token);
    if (!dependency) {
      throw new Error(`未找到依赖: ${token}`);
    }
    
    if (typeof dependency === 'function') {
      return new dependency();
    }
    
    return dependency;
  }
}

function inject(token) {
  return createDecorator((target, property, descriptor) => {
    if (descriptor) {
      // 方法参数注入
      const originalMethod = descriptor.value;
      
      descriptor.value = function(...args) {
        // 解析依赖
        const dependency = DependencyContainer.resolve(token);
        return originalMethod.call(this, dependency, ...args);
      };
      
      return descriptor;
    } else {
      // 属性注入
      return {
        get() {
          return DependencyContainer.resolve(token);
        },
        enumerable: true,
        configurable: true
      };
    }
  });
}

// 3.7 路由装饰器(类似Angular/NestJS)
class Router {
  static routes = new Map();
  
  static get(path) {
    return createDecorator((target, property, descriptor) => {
      const originalMethod = descriptor.value;
      const routeKey = `GET ${path}`;
      
      this.routes.set(routeKey, {
        controller: target.constructor.name,
        method: property,
        handler: originalMethod
      });
      
      descriptor.value = function(...args) {
        console.log(`路由: ${routeKey}`);
        return originalMethod.apply(this, args);
      };
      
      return descriptor;
    });
  }
  
  static post(path) {
    return createDecorator((target, property, descriptor) => {
      const originalMethod = descriptor.value;
      const routeKey = `POST ${path}`;
      
      this.routes.set(routeKey, {
        controller: target.constructor.name,
        method: property,
        handler: originalMethod
      });
      
      return descriptor;
    });
  }
  
  static handleRequest(method, path) {
    const routeKey = `${method} ${path}`;
    const route = this.routes.get(routeKey);
    
    if (route) {
      console.log(`处理请求: ${routeKey}`);
      // 实际中会创建控制器实例并调用方法
      return route.handler;
    }
    
    return null;
  }
}

// 3.8 验证装饰器
class Validator {
  static validate(target, property, value) {
    const validations = target.constructor.__validations;
    if (validations && validations[property]) {
      for (const validation of validations[property]) {
        if (!validation.validator(value)) {
          throw new Error(validation.message || `验证失败: ${property}`);
        }
      }
    }
    return true;
  }
  
  static required(message = '该字段是必填的') {
    return createDecorator((target, property, descriptor) => {
      if (descriptor) {
        // 方法参数验证
        const originalMethod = descriptor.value;
        
        descriptor.value = function(...args) {
          const value = args[0];
          if (!value && value !== 0 && value !== false) {
            throw new Error(message);
          }
          return originalMethod.apply(this, args);
        };
        
        return descriptor;
      } else {
        // 属性验证
        if (!target.constructor.__validations) {
          target.constructor.__validations = {};
        }
        
        if (!target.constructor.__validations[property]) {
          target.constructor.__validations[property] = [];
        }
        
        target.constructor.__validations[property].push({
          validator: value => value != null && value !== '',
          message
        });
        
        // 创建getter/setter
        const privateProp = `_${property}`;
        
        return {
          get() {
            return this[privateProp];
          },
          set(value) {
            this[privateProp] = value;
          },
          enumerable: true,
          configurable: true
        };
      }
    });
  }
  
  static minLength(length, message) {
    return createDecorator((target, property) => {
      if (!target.constructor.__validations) {
        target.constructor.__validations = {};
      }
      
      if (!target.constructor.__validations[property]) {
        target.constructor.__validations[property] = [];
      }
      
      target.constructor.__validations[property].push({
        validator: value => !value || value.length >= length,
        message: message || `长度不能少于 ${length} 个字符`
      });
    });
  }
  
  static maxLength(length, message) {
    return createDecorator((target, property) => {
      if (!target.constructor.__validations) {
        target.constructor.__validations = {};
      }
      
      if (!target.constructor.__validations[property]) {
        target.constructor.__validations[property] = [];
      }
      
      target.constructor.__validations[property].push({
        validator: value => !value || value.length <= length,
        message: message || `长度不能超过 ${length} 个字符`
      });
    });
  }
}

// 使用高级装饰器
@classDecorator('用户控制器')
class UserController {
  @Router.get('/users')
  getAllUsers() {
    return ['Alice', 'Bob', 'Charlie'];
  }
  
  @Router.post('/users')
  createUser(@Validator.required() name) {
    return { id: 1, name };
  }
}

// 用户模型
class User {
  @Validator.required('用户名是必填的')
  @Validator.minLength(3, '用户名至少3个字符')
  @Validator.maxLength(20, '用户名最多20个字符')
  username;
  
  @Validator.required('密码是必填的')
  @Validator.minLength(6, '密码至少6个字符')
  password;
  
  constructor(username, password) {
    this.username = username;
    this.password = password;
  }
  
  validate() {
    for (const prop in this) {
      if (this.hasOwnProperty(prop)) {
        Validator.validate(this, prop, this[prop]);
      }
    }
  }
}

// 测试
const user = new User('alice', 'password123');
user.validate(); // 成功

try {
  const invalidUser = new User('a', '123');
  invalidUser.validate(); // 抛出错误
} catch (error) {
  console.error(error.message);
}

四、类型推断与类型系统

类型推断实现
javascript 复制代码
// 4.1 类型推断引擎
class TypeInferenceEngine {
  constructor() {
    this.typeRegistry = new Map();
    this.variableTypes = new Map();
  }
  
  // 推断变量类型
  inferVariableType(name, value) {
    let inferredType = this.inferValueType(value);
    
    // 检查是否已经声明过类型
    if (this.variableTypes.has(name)) {
      const declaredType = this.variableTypes.get(name);
      if (!this.isCompatible(inferredType, declaredType)) {
        throw new Error(`类型不匹配: 变量 ${name} 声明为 ${declaredType}, 但推断为 ${inferredType}`);
      }
      return declaredType;
    }
    
    // 记录推断的类型
    this.variableTypes.set(name, inferredType);
    return inferredType;
  }
  
  // 推断值类型
  inferValueType(value) {
    if (value === null) return 'null';
    if (value === undefined) return 'undefined';
    
    const type = typeof value;
    
    if (type === 'object') {
      if (Array.isArray(value)) {
        // 推断数组元素类型
        if (value.length === 0) return 'any[]';
        const elementType = this.inferValueType(value[0]);
        return `${elementType}[]`;
      }
      
      if (value instanceof Date) return 'Date';
      if (value instanceof RegExp) return 'RegExp';
      
      // 推断对象结构
      const structure = {};
      for (const key in value) {
        if (value.hasOwnProperty(key)) {
          structure[key] = this.inferValueType(value[key]);
        }
      }
      return JSON.stringify(structure);
    }
    
    return type;
  }
  
  // 检查类型兼容性
  isCompatible(type1, type2) {
    if (type1 === type2) return true;
    
    // 处理any类型
    if (type1 === 'any' || type2 === 'any') return true;
    
    // 处理数组类型
    if (type1.endsWith('[]') && type2.endsWith('[]')) {
      const elementType1 = type1.slice(0, -2);
      const elementType2 = type2.slice(0, -2);
      return this.isCompatible(elementType1, elementType2);
    }
    
    // 处理对象类型
    if (type1.startsWith('{') && type2.startsWith('{')) {
      try {
        const obj1 = JSON.parse(type1);
        const obj2 = JSON.parse(type2);
        
        for (const key in obj1) {
          if (obj1.hasOwnProperty(key)) {
            if (!obj2[key] || !this.isCompatible(obj1[key], obj2[key])) {
              return false;
            }
          }
        }
        return true;
      } catch {
        return false;
      }
    }
    
    return false;
  }
  
  // 推断函数返回类型
  inferFunctionReturn(func, args) {
    try {
      const result = func.apply(null, args);
      return this.inferValueType(result);
    } catch {
      return 'any';
    }
  }
}

// 使用示例
const engine = new TypeInferenceEngine();

const variables = {
  name: 'Alice',
  age: 30,
  scores: [95, 88, 92],
  profile: {
    email: 'alice@example.com',
    active: true
  }
};

for (const [name, value] of Object.entries(variables)) {
  const type = engine.inferVariableType(name, value);
  console.log(`${name}: ${type}`);
}

// 4.2 联合类型推断
function inferUnionType(values) {
  const types = new Set();
  
  for (const value of values) {
    const engine = new TypeInferenceEngine();
    types.add(engine.inferValueType(value));
  }
  
  return Array.from(types).join(' | ');
}

console.log(inferUnionType([1, 'hello', true])); // "number | string | boolean"

// 4.3 上下文类型推断
class ContextualTyping {
  static inferWithContext(value, context) {
    const engine = new TypeInferenceEngine();
    const valueType = engine.inferValueType(value);
    
    // 如果有上下文类型,检查兼容性
    if (context.expectedType) {
      if (!engine.isCompatible(valueType, context.expectedType)) {
        throw new Error(`上下文类型不匹配: 期望 ${context.expectedType}, 实际 ${valueType}`);
      }
      return context.expectedType;
    }
    
    return valueType;
  }
}

const context = { expectedType: 'string' };
console.log(ContextualTyping.inferWithContext('hello', context)); // "string"
// ContextualTyping.inferWithContext(123, context); // 抛出错误
高级类型系统
javascript 复制代码
// 4.4 条件类型模拟
class ConditionalType {
  static extends(T, U) {
    // 简化实现:检查T是否可以赋值给U
    return T === U || T === 'any';
  }
  
  static extract(T, U) {
    // 模拟 Extract<T, U>
    if (this.extends(T, U)) {
      return T;
    }
    return 'never';
  }
  
  static exclude(T, U) {
    // 模拟 Exclude<T, U>
    if (this.extends(T, U)) {
      return 'never';
    }
    return T;
  }
  
  static nonNullable(T) {
    // 模拟 NonNullable<T>
    if (T === 'null' || T === 'undefined') {
      return 'never';
    }
    return T;
  }
  
  static returnType(func) {
    // 模拟 ReturnType<T>
    try {
      const result = func();
      const engine = new TypeInferenceEngine();
      return engine.inferValueType(result);
    } catch {
      return 'any';
    }
  }
  
  static parameters(func) {
    // 模拟 Parameters<T>
    const funcStr = func.toString();
    const paramMatch = funcStr.match(/\(([^)]*)\)/);
    
    if (paramMatch) {
      const params = paramMatch[1].split(',').map(p => p.trim());
      return params.map(param => {
        const [name, type] = param.split(':').map(s => s.trim());
        return type || 'any';
      });
    }
    
    return [];
  }
}

// 使用示例
console.log(ConditionalType.extends('string', 'string')); // true
console.log(ConditionalType.extract('string | number', 'string')); // "string"
console.log(ConditionalType.exclude('string | number', 'string')); // "number"
console.log(ConditionalType.nonNullable('string | null')); // "string"

function sampleFunc(x, y) {
  return x + y;
}

console.log(ConditionalType.returnType(() => sampleFunc(1, 2))); // "number"
console.log(ConditionalType.parameters(sampleFunc)); // ["any", "any"]

// 4.5 映射类型模拟
class MappedType {
  static partial(T) {
    // 模拟 Partial<T>
    if (typeof T === 'string' && T.startsWith('{')) {
      try {
        const obj = JSON.parse(T);
        const result = {};
        for (const key in obj) {
          result[key] = obj[key] + '?'; // 添加可选标记
        }
        return JSON.stringify(result);
      } catch {
        return T;
      }
    }
    return T;
  }
  
  static required(T) {
    // 模拟 Required<T>
    if (typeof T === 'string' && T.startsWith('{')) {
      try {
        const obj = JSON.parse(T);
        const result = {};
        for (const key in obj) {
          const type = obj[key].endsWith('?') ? obj[key].slice(0, -1) : obj[key];
          result[key] = type;
        }
        return JSON.stringify(result);
      } catch {
        return T;
      }
    }
    return T;
  }
  
  static readonly(T) {
    // 模拟 Readonly<T>
    if (typeof T === 'string' && T.startsWith('{')) {
      try {
        const obj = JSON.parse(T);
        const result = {};
        for (const key in obj) {
          result[key] = 'readonly ' + obj[key];
        }
        return JSON.stringify(result);
      } catch {
        return T;
      }
    }
    return T;
  }
  
  static record(K, T) {
    // 模拟 Record<K, T>
    const keys = K.split(' | ');
    const result = {};
    keys.forEach(key => {
      const cleanKey = key.replace(/['"]/g, '');
      result[cleanKey] = T;
    });
    return JSON.stringify(result);
  }
}

// 使用示例
const userType = JSON.stringify({
  name: 'string',
  age: 'number?',
  email: 'string'
});

console.log('Partial:', MappedType.partial(userType));
console.log('Required:', MappedType.required(userType));
console.log('Readonly:', MappedType.readonly(userType));
console.log('Record:', MappedType.record('"id" | "name"', 'string'));

五、模块与命名空间

TypeScript模块系统
javascript 复制代码
// 5.1 模块加载器模拟
class TypeScriptModuleLoader {
  constructor() {
    this.modules = new Map();
    this.exports = new Map();
    this.moduleCache = new Map();
  }
  
  // 定义模块
  define(moduleId, dependencies, factory) {
    this.modules.set(moduleId, {
      dependencies,
      factory,
      exports: {},
      resolved: false
    });
  }
  
  // 解析模块
  async require(moduleId) {
    if (this.moduleCache.has(moduleId)) {
      return this.moduleCache.get(moduleId);
    }
    
    const module = this.modules.get(moduleId);
    if (!module) {
      // 尝试作为外部模块加载
      return this.loadExternalModule(moduleId);
    }
    
    // 解析依赖
    const depPromises = module.dependencies.map(dep => {
      if (dep === 'exports') return {};
      if (dep === 'require') return this.require.bind(this);
      if (dep === 'module') return { id: moduleId, exports: {} };
      return this.require(dep);
    });
    
    const dependencies = await Promise.all(depPromises);
    
    // 执行工厂函数
    const exports = module.factory.apply(null, dependencies);
    
    // 缓存结果
    module.exports = exports || {};
    module.resolved = true;
    this.moduleCache.set(moduleId, module.exports);
    
    return module.exports;
  }
  
  // 加载外部模块(模拟)
  async loadExternalModule(moduleId) {
    console.log(`加载外部模块: ${moduleId}`);
    
    // 模拟动态导入
    if (moduleId.startsWith('.')) {
      // 相对路径
      const mockModule = await this.mockLoadModule(moduleId);
      return mockModule;
    }
    
    // 假设是npm包
    return {};
  }
  
  async mockLoadModule(path) {
    // 模拟模块内容
    const mockModules = {
      './math': {
        add: (a, b) => a + b,
        subtract: (a, b) => a - b
      },
      './utils': {
        format: str => str.toUpperCase(),
        parse: str => JSON.parse(str)
      }
    };
    
    await new Promise(resolve => setTimeout(resolve, 100)); // 模拟延迟
    
    return mockModules[path] || {};
  }
  
  // 编译TypeScript模块
  compileModule(source) {
    // 移除类型注解
    const jsCode = source
      .replace(/:\s*\w+(?:<[^>]*>)?(?=\s*[;,=){}])/g, '') // 移除类型注解
      .replace(/export\s+(?:default\s+)?/g, '') // 简化导出
      .replace(/import\s+.*?from\s+['"](.+)['"]/g, '// 导入: $1'); // 注释化导入
    
    return jsCode;
  }
}

// 使用示例
const loader = new TypeScriptModuleLoader();

// 定义TypeScript模块
const mathSource = `
export function add(a: number, b: number): number {
  return a + b;
}

export function subtract(a: number, b: number): number {
  return a - b;
}

export default class Calculator {
  multiply(a: number, b: number): number {
    return a * b;
  }
}
`;

const appSource = `
import { add } from './math';
import Calculator from './math';

export function calculate(): number {
  const calc = new Calculator();
  return add(10, calc.multiply(2, 3));
}
`;

// 编译模块
const mathJS = loader.compileModule(mathSource);
const appJS = loader.compileModule(appSource);

console.log('编译后的math模块:');
console.log(mathJS);

console.log('编译后的app模块:');
console.log(appJS);

// 5.2 命名空间实现
class NamespaceManager {
  static namespaces = new Map();
  
  static create(namespace, contents) {
    if (!this.namespaces.has(namespace)) {
      this.namespaces.set(namespace, {});
    }
    
    const ns = this.namespaces.get(namespace);
    Object.assign(ns, contents);
    
    // 暴露到全局
    const parts = namespace.split('.');
    let current = globalThis;
    
    for (let i = 0; i < parts.length; i++) {
      const part = parts[i];
      if (i === parts.length - 1) {
        current[part] = ns;
      } else {
        current[part] = current[part] || {};
        current = current[part];
      }
    }
    
    return ns;
  }
  
  static get(namespace) {
    return this.namespaces.get(namespace);
  }
  
  static export(namespace, exports) {
    const ns = this.get(namespace) || this.create(namespace, {});
    Object.assign(ns, exports);
  }
}

// 使用命名空间
NamespaceManager.create('MyApp.Math', {
  add: (a, b) => a + b,
  subtract: (a, b) => a - b,
  constants: {
    PI: 3.14159,
    E: 2.71828
  }
});

NamespaceManager.create('MyApp.Utils', {
  format: str => str.toUpperCase(),
  validate: obj => obj != null
});

// 访问命名空间
console.log(MyApp.Math.add(2, 3)); // 5
console.log(MyApp.Utils.format('hello')); // "HELLO"

六、工程化与构建工具集成

TypeScript配置与编译
javascript 复制代码
// 6.1 TypeScript配置解析器
class TSConfigParser {
  static parse(config) {
    const defaults = {
      compilerOptions: {
        target: 'es5',
        module: 'commonjs',
        strict: false,
        esModuleInterop: true,
        skipLibCheck: true,
        forceConsistentCasingInFileNames: true
      },
      include: ['src/**/*'],
      exclude: ['node_modules', 'dist']
    };
    
    return this.deepMerge(defaults, config);
  }
  
  static deepMerge(target, source) {
    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        if (this.isObject(source[key]) && this.isObject(target[key])) {
          this.deepMerge(target[key], source[key]);
        } else {
          target[key] = source[key];
        }
      }
    }
    return target;
  }
  
  static isObject(item) {
    return item && typeof item === 'object' && !Array.isArray(item);
  }
  
  static generateCompilerCommand(config) {
    const options = config.compilerOptions;
    const args = [];
    
    for (const [key, value] of Object.entries(options)) {
      const argName = `--${key}`;
      
      if (typeof value === 'boolean') {
        if (value) args.push(argName);
      } else if (typeof value === 'string') {
        args.push(`${argName} ${value}`);
      } else if (Array.isArray(value)) {
        args.push(`${argName} ${value.join(',')}`);
      }
    }
    
    return `tsc ${args.join(' ')}`;
  }
}

// 示例配置
const tsconfig = {
  compilerOptions: {
    target: 'es2020',
    module: 'esnext',
    lib: ['es2020', 'dom'],
    outDir: './dist',
    rootDir: './src',
    strict: true,
    moduleResolution: 'node',
    baseUrl: '.',
    paths: {
      '@/*': ['src/*']
    },
    allowSyntheticDefaultImports: true
  },
  include: ['src/**/*.ts', 'src/**/*.tsx'],
  exclude: ['node_modules']
};

const parsedConfig = TSConfigParser.parse(tsconfig);
console.log('解析后的配置:', parsedConfig);
console.log('编译器命令:', TSConfigParser.generateCompilerCommand(parsedConfig));

// 6.2 构建管道模拟
class TypeScriptBuildPipeline {
  constructor(config) {
    this.config = config;
    this.steps = [];
  }
  
  addStep(name, processor) {
    this.steps.push({ name, processor });
    return this;
  }
  
  async build(sourceFiles) {
    console.log('开始构建TypeScript项目...');
    
    let processedFiles = sourceFiles;
    
    for (const step of this.steps) {
      console.log(`执行步骤: ${step.name}`);
      
      if (Array.isArray(processedFiles)) {
        const results = await Promise.all(
          processedFiles.map(file => step.processor(file, this.config))
        );
        processedFiles = results;
      } else {
        processedFiles = await step.processor(processedFiles, this.config);
      }
    }
    
    console.log('构建完成!');
    return processedFiles;
  }
}

// 构建步骤处理器
const processors = {
  // 类型检查
  typeCheck: async (file, config) => {
    console.log(`类型检查: ${file.name}`);
    // 模拟类型检查
    if (file.name.includes('error')) {
      throw new Error(`类型错误: ${file.name}`);
    }
    return file;
  },
  
  // 编译
  compile: async (file, config) => {
    console.log(`编译: ${file.name}`);
    
    // 模拟编译过程
    const jsCode = file.content
      .replace(/:\s*\w+/g, '') // 移除类型注解
      .replace(/interface\s+\w+\s*\{[^}]+\}/g, '') // 移除接口
      .replace(/export\s+type\s+\w+/g, '') // 移除类型导出
      .trim();
    
    return {
      ...file,
      content: jsCode,
      extension: '.js'
    };
  },
  
  // 打包
  bundle: async (files, config) => {
    console.log('打包文件...');
    
    const bundleContent = files
      .map(file => `// ${file.name}\n${file.content}`)
      .join('\n\n');
    
    return {
      name: 'bundle.js',
      content: bundleContent,
      size: bundleContent.length
    };
  },
  
  // 压缩
  minify: async (file, config) => {
    console.log('压缩代码...');
    
    // 简单压缩:移除空格和注释
    const minified = file.content
      .replace(/\/\/.*$/gm, '')
      .replace(/\/\*[\s\S]*?\*\//g, '')
      .replace(/\s+/g, ' ')
      .trim();
    
    return {
      ...file,
      content: minified,
      size: minified.length
    };
  }
};

// 模拟源文件
const sourceFiles = [
  {
    name: 'math.ts',
    content: `
      export function add(a: number, b: number): number {
        return a + b;
      }
      
      export function subtract(a: number, b: number): number {
        return a - b;
      }
    `
  },
  {
    name: 'app.ts',
    content: `
      import { add } from './math';
      
      export function calculate(): number {
        return add(1, 2);
      }
    `
  }
];

// 创建构建管道
const pipeline = new TypeScriptBuildPipeline(tsconfig)
  .addStep('类型检查', processors.typeCheck)
  .addStep('编译', processors.compile)
  .addStep('打包', processors.bundle)
  .addStep('压缩', processors.minify);

// 执行构建
pipeline.build(sourceFiles).then(result => {
  console.log('构建结果:', result);
});

七、实战应用: 在JavaScript项目中引入TypeScript

渐进式迁移策略
javascript 复制代码
// 7.1 混合项目结构管理
class HybridProjectManager {
  constructor(options = {}) {
    this.options = {
      tsDir: 'src/ts',
      jsDir: 'src/js',
      buildDir: 'dist',
      allowJS: true,
      checkJS: true,
      ...options
    };
    
    this.fileRegistry = new Map();
  }
  
  // 注册文件
  registerFile(path, type) {
    this.fileRegistry.set(path, {
      type,
      dependencies: [],
      errors: []
    });
    
    // 自动检测文件类型
    if (path.endsWith('.ts') || path.endsWith('.tsx')) {
      this.fileRegistry.get(path).type = 'typescript';
    } else if (path.endsWith('.js') || path.endsWith('.jsx')) {
      this.fileRegistry.get(path).type = 'javascript';
    }
  }
  
  // 分析依赖关系
  analyzeDependencies(path) {
    const file = this.fileRegistry.get(path);
    if (!file) return;
    
    const content = this.readFile(path);
    const dependencies = [];
    
    // 解析导入语句
    const importRegex = /import\s+(?:.*?from\s+)?['"]([^'"]+)['"]/g;
    let match;
    
    while ((match = importRegex.exec(content)) !== null) {
      dependencies.push(match[1]);
    }
    
    file.dependencies = dependencies;
  }
  
  // 检查混合项目问题
  checkHybridIssues() {
    const issues = [];
    
    for (const [path, file] of this.fileRegistry) {
      // 检查TypeScript文件是否导入了未定义的JavaScript模块
      if (file.type === 'typescript') {
        for (const dep of file.dependencies) {
          if (dep.endsWith('.js')) {
            const depPath = this.resolvePath(path, dep);
            const depFile = this.fileRegistry.get(depPath);
            
            if (depFile && depFile.type === 'javascript') {
              issues.push({
                type: 'ts-imports-js',
                message: `TypeScript文件 ${path} 导入了JavaScript文件 ${depPath}`,
                severity: 'warning',
                suggestion: '考虑将JavaScript文件迁移为TypeScript或添加类型声明'
              });
            }
          }
        }
      }
      
      // 检查JavaScript文件是否缺少JSDoc注释
      if (file.type === 'javascript' && this.options.checkJS) {
        const content = this.readFile(path);
        const hasJSDoc = /\/\*\*\s*\n(?:[^*]|\*(?!\/))*\*\//.test(content);
        
        if (!hasJSDoc) {
          issues.push({
            type: 'missing-jsdoc',
            message: `JavaScript文件 ${path} 缺少JSDoc注释`,
            severity: 'info',
            suggestion: '添加JSDoc注释以提供类型信息'
          });
        }
      }
    }
    
    return issues;
  }
  
  // 生成迁移建议
  generateMigrationPlan() {
    const plan = {
      phase1: [], // 立即迁移的文件
      phase2: [], // 可以稍后迁移的文件
      declarations: [] // 需要创建的类型声明文件
    };
    
    for (const [path, file] of this.fileRegistry) {
      if (file.type === 'javascript') {
        // 分析复杂性
        const complexity = this.assessComplexity(path);
        
        if (complexity <= 2) {
          plan.phase1.push(path);
        } else {
          plan.phase2.push(path);
        }
        
        // 检查是否需要声明文件
        if (file.dependencies.some(dep => dep.startsWith('@types/'))) {
          plan.declarations.push(path);
        }
      }
    }
    
    return plan;
  }
  
  // 评估文件复杂性
  assessComplexity(path) {
    const content = this.readFile(path);
    let score = 0;
    
    // 基于行数
    const lines = content.split('\n').length;
    if (lines > 100) score += 2;
    else if (lines > 50) score += 1;
    
    // 基于函数数量
    const functionCount = (content.match(/function\s+\w+|\b\w+\s*=/g) || []).length;
    score += Math.min(Math.floor(functionCount / 5), 3);
    
    // 基于外部依赖
    const importCount = (content.match(/import\s+|require\(/g) || []).length;
    score += Math.min(importCount, 2);
    
    return score;
  }
  
  // 工具方法
  readFile(path) {
    // 模拟文件读取
    return '模拟文件内容';
  }
  
  resolvePath(base, relative) {
    // 简化路径解析
    return relative;
  }
}

// 使用示例
const manager = new HybridProjectManager({
  tsDir: 'src/ts',
  jsDir: 'src/js',
  checkJS: true
});

// 注册文件
manager.registerFile('src/js/user.js', 'javascript');
manager.registerFile('src/ts/auth.ts', 'typescript');
manager.registerFile('src/js/utils.js', 'javascript');

// 分析问题
const issues = manager.checkHybridIssues();
console.log('发现的问题:', issues);

// 生成迁移计划
const migrationPlan = manager.generateMigrationPlan();
console.log('迁移计划:', migrationPlan);

// 7.2 类型声明生成器
class TypeDeclarationGenerator {
  static generateFromJS(jsCode, options = {}) {
    const declarations = [];
    
    // 解析函数
    const functionRegex = /function\s+(\w+)\s*\(([^)]*)\)/g;
    let match;
    
    while ((match = functionRegex.exec(jsCode)) !== null) {
      const [, funcName, params] = match;
      const paramTypes = this.inferParamTypes(params);
      const returnType = this.inferReturnType(jsCode, funcName);
      
      declarations.push(
        `declare function ${funcName}(${paramTypes}): ${returnType};`
      );
    }
    
    // 解析类
    const classRegex = /class\s+(\w+)/g;
    while ((match = classRegex.exec(jsCode)) !== null) {
      const [, className] = match;
      const classDeclaration = this.generateClassDeclaration(jsCode, className);
      declarations.push(classDeclaration);
    }
    
    // 解析变量导出
    const exportRegex = /exports\.(\w+)\s*=/g;
    while ((match = exportRegex.exec(jsCode)) !== null) {
      const [, exportName] = match;
      const type = this.inferVariableType(jsCode, exportName);
      declarations.push(`declare const ${exportName}: ${type};`);
    }
    
    return declarations.join('\n');
  }
  
  static inferParamTypes(paramsStr) {
    const params = paramsStr.split(',').map(p => p.trim()).filter(p => p);
    
    return params.map((param, index) => {
      const [name, defaultValue] = param.split('=').map(s => s.trim());
      let type = 'any';
      
      if (defaultValue) {
        if (defaultValue.includes("'") || defaultValue.includes('"')) {
          type = 'string';
        } else if (defaultValue === 'true' || defaultValue === 'false') {
          type = 'boolean';
        } else if (!isNaN(parseFloat(defaultValue))) {
          type = 'number';
        } else if (defaultValue === '[]') {
          type = 'any[]';
        } else if (defaultValue === '{}') {
          type = 'object';
        }
      }
      
      return `${name}: ${type}`;
    }).join(', ');
  }
  
  static inferReturnType(jsCode, funcName) {
    // 简化实现:检查return语句
    const returnRegex = new RegExp(`function\\s+${funcName}[^{]*{([^}]*return[^;]+;)?`, 'i');
    const match = jsCode.match(returnRegex);
    
    if (match && match[1]) {
      const returnExpr = match[1].replace('return', '').trim();
      
      if (returnExpr.includes("'") || returnExpr.includes('"')) {
        return 'string';
      } else if (returnExpr === 'true' || returnExpr === 'false') {
        return 'boolean';
      } else if (!isNaN(parseFloat(returnExpr))) {
        return 'number';
      }
    }
    
    return 'any';
  }
  
  static generateClassDeclaration(jsCode, className) {
    const declaration = [`declare class ${className} {`];
    
    // 提取构造函数
    const constructorRegex = new RegExp(`constructor\\(([^)]*)\\)`, 'g');
    const constructorMatch = constructorRegex.exec(jsCode);
    
    if (constructorMatch) {
      const params = constructorMatch[1];
      const paramTypes = this.inferParamTypes(params);
      declaration.push(`  constructor(${paramTypes});`);
    }
    
    // 提取方法
    const methodRegex = new RegExp(`${className}\\.prototype\\.(\\w+)\\s*=\\s*function`, 'g');
    while ((match = methodRegex.exec(jsCode)) !== null) {
      const [, methodName] = match;
      declaration.push(`  ${methodName}(): any;`);
    }
    
    declaration.push('}');
    return declaration.join('\n');
  }
  
  static inferVariableType(jsCode, varName) {
    const regex = new RegExp(`${varName}\\s*=\\s*([^;]+)`, 'g');
    const match = regex.exec(jsCode);
    
    if (match) {
      const value = match[1].trim();
      
      if (value.startsWith('[')) return 'any[]';
      if (value.startsWith('{')) return 'object';
      if (value.includes("'") || value.includes('"')) return 'string';
      if (value === 'true' || value === 'false') return 'boolean';
      if (!isNaN(parseFloat(value))) return 'number';
    }
    
    return 'any';
  }
}

// 生成类型声明示例
const jsCode = `
function greet(name) {
  return 'Hello, ' + name;
}

class User {
  constructor(name, age = 18) {
    this.name = name;
    this.age = age;
  }
  
  sayHello() {
    return greet(this.name);
  }
}

exports.greet = greet;
exports.User = User;
exports.VERSION = '1.0.0';
`;

const declarations = TypeDeclarationGenerator.generateFromJS(jsCode);
console.log('生成的类型声明:');
console.log(declarations);

八、性能优化与最佳实践

TypeScript编译优化
javascript 复制代码
// 8.1 增量编译
class IncrementalCompiler {
  constructor() {
    this.fileCache = new Map();
    this.dependencyGraph = new Map();
    this.lastCompileTime = Date.now();
  }
  
  // 检查文件是否需要重新编译
  needsRecompile(filePath, content) {
    const cached = this.fileCache.get(filePath);
    
    if (!cached) {
      return true; // 新文件
    }
    
    if (cached.content !== content) {
      return true; // 内容改变
    }
    
    // 检查依赖是否改变
    const dependencies = this.dependencyGraph.get(filePath) || [];
    for (const dep of dependencies) {
      const depCached = this.fileCache.get(dep);
      if (!depCached || depCached.timestamp > cached.timestamp) {
        return true; // 依赖已更新
      }
    }
    
    return false; // 无需重新编译
  }
  
  // 增量编译
  incrementalCompile(files) {
    const toCompile = [];
    const startTime = Date.now();
    
    for (const file of files) {
      if (this.needsRecompile(file.path, file.content)) {
        toCompile.push(file);
      }
    }
    
    console.log(`需要重新编译 ${toCompile.length} 个文件`);
    
    if (toCompile.length === 0) {
      console.log('没有文件需要重新编译,使用缓存');
      return this.getCachedOutput();
    }
    
    // 执行编译
    const results = this.compileFiles(toCompile);
    
    // 更新缓存
    for (const file of toCompile) {
      this.fileCache.set(file.path, {
        content: file.content,
        timestamp: startTime,
        output: results[file.path]
      });
    }
    
    this.lastCompileTime = startTime;
    
    return results;
  }
  
  compileFiles(files) {
    // 简化编译过程
    const results = {};
    
    for (const file of files) {
      results[file.path] = file.content.replace(/:\s*\w+/g, '');
    }
    
    return results;
  }
  
  getCachedOutput() {
    const output = {};
    
    for (const [path, cached] of this.fileCache) {
      output[path] = cached.output;
    }
    
    return output;
  }
}

// 8.2 项目引用优化
class ProjectReferenceOptimizer {
  static optimize(config, projects) {
    const optimized = { ...config };
    
    // 分析项目依赖
    const dependencies = this.analyzeDependencies(projects);
    
    // 设置项目引用
    optimized.compilerOptions = {
      ...optimized.compilerOptions,
      composite: true,
      declaration: true,
      declarationMap: true,
      incremental: true
    };
    
    optimized.references = dependencies.map(dep => ({ path: dep }));
    
    return optimized;
  }
  
  static analyzeDependencies(projects) {
    const graph = new Map();
    
    // 构建依赖图
    for (const project of projects) {
      const deps = this.extractImports(project.source);
      graph.set(project.name, deps);
    }
    
    // 拓扑排序
    return this.topologicalSort(graph);
  }
  
  static extractImports(source) {
    const imports = [];
    const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
    let match;
    
    while ((match = importRegex.exec(source)) !== null) {
      imports.push(match[1]);
    }
    
    return imports;
  }
  
  static topologicalSort(graph) {
    const visited = new Set();
    const result = [];
    
    const visit = (node) => {
      if (visited.has(node)) return;
      visited.add(node);
      
      const dependencies = graph.get(node) || [];
      for (const dep of dependencies) {
        visit(dep);
      }
      
      result.push(node);
    };
    
    for (const node of graph.keys()) {
      visit(node);
    }
    
    return result;
  }
}

// 8.3 内存优化
class TypeScriptMemoryOptimizer {
  constructor() {
    this.memoryCache = new Map();
    this.maxCacheSize = 100;
  }
  
  // 编译结果缓存
  cacheCompilationResult(filePath, ast, diagnostics, output) {
    const cacheEntry = {
      ast,
      diagnostics,
      output,
      timestamp: Date.now(),
      size: this.calculateSize(ast) + this.calculateSize(output)
    };
    
    this.memoryCache.set(filePath, cacheEntry);
    this.cleanupCache();
  }
  
  // 获取缓存结果
  getCachedResult(filePath) {
    const cached = this.memoryCache.get(filePath);
    if (cached) {
      // 更新访问时间
      cached.timestamp = Date.now();
      return cached;
    }
    return null;
  }
  
  // 清理缓存
  cleanupCache() {
    if (this.memoryCache.size <= this.maxCacheSize) {
      return;
    }
    
    // LRU缓存清理
    const entries = Array.from(this.memoryCache.entries());
    entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
    
    const toRemove = entries.slice(0, entries.length - this.maxCacheSize);
    
    for (const [key] of toRemove) {
      this.memoryCache.delete(key);
    }
  }
  
  // 计算对象大小
  calculateSize(obj) {
    const str = JSON.stringify(obj);
    return str.length * 2; // 粗略估计(UTF-16)
  }
  
  // AST节点缓存池
  createASTNodePool() {
    const pool = new Map();
    
    return {
      getNode(type, props) {
        const key = `${type}:${JSON.stringify(props)}`;
        
        if (pool.has(key)) {
          return pool.get(key);
        }
        
        const node = { type, ...props };
        pool.set(key, node);
        
        return node;
      },
      
      clear() {
        pool.clear();
      },
      
      get size() {
        return pool.size;
      }
    };
  }
}
TypeScript最佳实践
javascript 复制代码
// 8.4 代码组织最佳实践
class TypeScriptBestPractices {
  static structureProject(projectType) {
    const structures = {
      library: {
        src: [
          'index.ts', // 主入口
          'types/',   // 类型定义
          'utils/',   // 工具函数
          'core/',    // 核心逻辑
          'tests/'    // 测试文件
        ],
        config: [
          'tsconfig.json',
          'tsconfig.build.json',
          'package.json',
          '.eslintrc.js'
        ],
        docs: 'README.md'
      },
      
      application: {
        src: [
          'main.ts',          // 应用入口
          'components/',      // 组件
          'services/',        // 服务层
          'models/',          // 数据模型
          'utils/',           // 工具函数
          'styles/',          // 样式文件
          'assets/',          // 静态资源
          'tests/'            // 测试
        ],
        config: [
          'tsconfig.json',
          'tsconfig.app.json',
          'package.json',
          'webpack.config.js'
        ],
        public: 'index.html'
      },
      
      node: {
        src: [
          'index.ts',         // 应用入口
          'controllers/',     // 控制器
          'services/',        // 服务层
          'models/',          // 数据模型
          'middleware/',      // 中间件
          'routes/',          // 路由
          'utils/',           // 工具函数
          'tests/'            // 测试
        ],
        config: [
          'tsconfig.json',
          'package.json',
          '.env',
          'dockerfile'
        ]
      }
    };
    
    return structures[projectType] || structures.library;
  }
  
  static namingConventions = {
    interfaces: {
      rule: '使用 PascalCase,以 I 开头',
      examples: ['IUser', 'IProductService', 'IRepository']
    },
    
    types: {
      rule: '使用 PascalCase',
      examples: ['UserData', 'ApiResponse', 'ConfigOptions']
    },
    
    classes: {
      rule: '使用 PascalCase',
      examples: ['UserService', 'DatabaseConnection', 'HttpClient']
    },
    
    variables: {
      rule: '使用 camelCase',
      examples: ['userName', 'productList', 'isLoading']
    },
    
    constants: {
      rule: '使用 UPPER_SNAKE_CASE',
      examples: ['MAX_RETRY_COUNT', 'API_BASE_URL', 'DEFAULT_TIMEOUT']
    },
    
    generics: {
      rule: '使用单个大写字母,T 开头',
      examples: ['T', 'K', 'V', 'TKey', 'TValue']
    }
  };
  
  static createTSConfig(projectType, options = {}) {
    const baseConfig = {
      compilerOptions: {
        target: 'es2020',
        module: 'commonjs',
        lib: ['es2020'],
        outDir: './dist',
        rootDir: './src',
        strict: true,
        esModuleInterop: true,
        skipLibCheck: true,
        forceConsistentCasingInFileNames: true
      }
    };
    
    const typeSpecific = {
      library: {
        compilerOptions: {
          declaration: true,
          declarationMap: true,
          sourceMap: true
        }
      },
      
      application: {
        compilerOptions: {
          jsx: 'react-jsx',
          moduleResolution: 'node',
          allowSyntheticDefaultImports: true
        }
      },
      
      node: {
        compilerOptions: {
          module: 'commonjs',
          target: 'es2020',
          lib: ['es2020']
        }
      }
    };
    
    return this.deepMerge(
      baseConfig,
      typeSpecific[projectType] || {},
      { compilerOptions: options }
    );
  }
  
  static deepMerge(...objects) {
    return objects.reduce((acc, obj) => {
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          if (this.isObject(obj[key]) && this.isObject(acc[key])) {
            acc[key] = this.deepMerge(acc[key], obj[key]);
          } else {
            acc[key] = obj[key];
          }
        }
      }
      return acc;
    }, {});
  }
  
  static isObject(item) {
    return item && typeof item === 'object' && !Array.isArray(item);
  }
  
  // 错误处理最佳实践
  static errorHandlingPatterns = {
    // 使用Result类型处理错误
    Result: `
type Result<T, E = Error> = 
  | { success: true; data: T }
  | { success: false; error: E };

function safeOperation(): Result<string> {
  try {
    const result = riskyOperation();
    return { success: true, data: result };
  } catch (error) {
    return { success: false, error: error as Error };
  }
}
    `,
    
    // 自定义错误类
    CustomError: `
class AppError extends Error {
  constructor(
    message: string,
    public code: string,
    public statusCode: number = 500
  ) {
    super(message);
    this.name = 'AppError';
  }
}

class ValidationError extends AppError {
  constructor(message: string) {
    super(message, 'VALIDATION_ERROR', 400);
    this.name = 'ValidationError';
  }
}
    `,
    
    // 错误边界
    ErrorBoundary: `
class ErrorBoundary {
  private errorHandlers = new Map<string, (error: Error) => void>();
  
  register(component: string, handler: (error: Error) => void) {
    this.errorHandlers.set(component, handler);
  }
  
  handle(component: string, error: Error) {
    const handler = this.errorHandlers.get(component);
    if (handler) {
      handler(error);
    } else {
      console.error(\`未处理的错误 (\${component}):\`, error);
    }
  }
}
    `
  };
}

// 使用最佳实践
console.log('库项目结构:', TypeScriptBestPractices.structureProject('library'));
console.log('命名约定:', TypeScriptBestPractices.namingConventions);

const libConfig = TypeScriptBestPractices.createTSConfig('library', {
  outDir: './lib',
  declarationDir: './types'
});

console.log('库TS配置:', JSON.stringify(libConfig, null, 2));

总结

TypeScript通过强大的类型系统、接口泛型、装饰器等特性,极大地提升了JavaScript代码的质量和开发体验。本文深入探讨了TypeScript的核心实现原理和高级特性,并提供了实际可用的代码示例。

核心要点总结:

  1. 类型系统: TypeScript通过编译时类型检查提供安全保障,运行时也可通过代理模式实现类型验证
  2. 接口与泛型: 通过设计模式模拟接口实现,泛型提供代码复用性和类型安全性
  3. 装饰器: 元编程的强大工具,实现依赖注入、验证、日志等横切关注点
  4. 类型推断: 自动推断变量类型,减少冗余的类型注解
  5. 模块与工程化: 完善的模块系统支持,与构建工具深度集成
  6. 最佳实践: 合理的项目结构、命名约定和错误处理策略

TypeScript不仅是JavaScript的类型超集,更是一种工程化实践。它将静态类型语言的严谨性与JavaScript的灵活性完美结合,成为现代前端开发不可或缺的工具。随着TypeScript的持续发展,其类型系统将变得更加智能和强大,为构建大型、可维护的应用程序提供坚实保障。

在实际项目中,应根据团队规模、项目复杂度和技术栈选择合适的TypeScript特性,平衡类型安全性和开发效率。通过渐进式迁移策略,即使现有JavaScript项目也能平滑过渡到TypeScript,享受类型系统带来的诸多好处。

相关推荐
一 乐3 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
C_心欲无痕4 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
清沫4 小时前
Claude Skills:Agent 能力扩展的新范式
前端·ai编程
yinuo5 小时前
前端跨页面通信终极指南:方案拆解、对比分析
前端
yinuo5 小时前
前端跨页面通讯终极指南⑨:IndexedDB 用法全解析
前端
xkxnq6 小时前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js
烛阴6 小时前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js
Van_Moonlight6 小时前
RN for OpenHarmony 实战 TodoList 项目:空状态占位图
javascript·开源·harmonyos
xkxnq6 小时前
第一阶段:Vue 基础入门(第 15天)
前端·javascript·vue.js
anyup7 小时前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos