💙 TypeScript 类型系统

深度解析编译器核心原理

基于源码深度解析
2026-03-06 | 技术深度解读

📑 目录

第一部分:基础架构

  • TypeScript 简介
  • 类型系统架构
  • 核心编译流程
  • 类型系统分层

第二部分:演进历史

  • 类型系统演进史
  • 版本特性对比

第三部分:核心类解析

  • Type / Symbol / Node
  • TypeChecker
  • Signature / FlowNode

第四部分:核心函数

  • 类型推断算法
  • 类型兼容性检查
  • 泛型实例化

💙 TypeScript 简介

TypeScript 是 JavaScript 的超集,添加了静态类型检查和其他特性。

核心特性

  • 静态类型系统
  • 类型推断
  • 泛型编程
  • 接口与类型别名
  • 高级类型操作

类型系统目标

  • 编译时错误检测
  • IDE 智能提示
  • 代码可维护性
  • 渐进式采用
  • 零运行时开销

🏗️ 类型系统架构

┌─────────────────────────────────────────┐
│            TypeScript 编译器             │
├─────────────────────────────────────────┤
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  │
│  │ Scanner │→ │ Parser  │→ │ Binder  │  │
│  └─────────┘  └─────────┘  └─────────┘  │
│       ↓            ↓            ↓        │
│  ┌─────────────────────────────────────┐│
│  │         TypeChecker (核心)           ││
│  │  • 类型推断                          ││
│  │  • 类型兼容性检查                    ││
│  │  • 控制流分析                        ││
│  └─────────────────────────────────────┘│
│       ↓                                  │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  │
│  │ Checker │→ │Emitter  │→ │   JS    │  │
│  └─────────┘  └─────────┘  └─────────┘  │
└─────────────────────────────────────────┘

⚙️ 核心编译流程

1. Scanner (扫描器) - 将源代码转换为 Token 流

2. Parser (解析器) - 将 Token 流转换为 AST

3. Binder (绑定器) - 创建 Symbol 并建立作用域

4. Checker (检查器) - 执行类型检查 ⭐核心

5. Emitter (发射器) - 生成 JavaScript 代码

// 创建 TypeChecker 的入口函数
export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
    // checker.ts 核心实现
    // 超过 50,000 行代码!
}

📊 类型系统分层

层次 职责 核心类型
语法层 AST 节点表示 Node, SyntaxKind
符号层 名称绑定 Symbol, SymbolTable
类型层 类型表示 Type, TypeFlags
关系层 类型兼容性 TypeComparer
控制流层 流程分析 FlowNode, FlowFlags

📜 类型系统演进史

2012 - TypeScript 0.8

  • 基础类型系统
  • 类和接口

2015 - TypeScript 1.5

  • ES6 模块支持
  • 装饰器

2016 - TypeScript 2.0

  • 不可空类型
  • 控制流分析

2018 - TypeScript 3.0

  • 未知类型
  • 项目引用

2020 - TypeScript 4.0

  • 可变元组类型
  • 标签元组元素

2023+ - TypeScript 5.x

  • 装饰器改进
  • const 类型参数

📈 版本特性对比

版本 关键特性 类型系统增强
2.0 strictNullChecks null/undefined 区分
2.8 条件类型 T extends U ? X : Y
3.0 unknown 类型安全的 any
4.0 可变元组 [...T, ...U]
4.1 模板字面量类型 `${T}`
4.7 extends 约束推断 类型参数推断改进
5.0 装饰器标准化 const 类型参数

🗄️ 核心数据结构

TypeScript 类型系统建立在三个核心数据结构之上:

Type (类型)

  • 表示程序中的类型
  • 包含类型标志和属性
  • 支持结构化类型

Symbol (符号)

  • 表示命名实体
  • 关联声明节点
  • 维护作用域信息

Node (节点)

  • AST 的基本单元
  • 表示语法结构
  • 包含父子关系

Signature (签名)

  • 函数/构造器签名
  • 参数和返回类型
  • 类型参数信息

🔷 Type 接口

// types.ts - 核心类型接口
export interface Type {
    flags: TypeFlags;           // 类型标志位
    symbol?: Symbol;            // 关联的符号
    pattern?: DestructuringPattern;
    aliasSymbol?: Symbol;       // 别名符号
    aliasTypeArguments?: readonly Type[];
}

// 类型标志位定义
export const enum TypeFlags {
    Any = 1 << 0,               // any 类型
    Unknown = 1 << 1,           // unknown 类型
    String = 1 << 2,            // string 类型
    Number = 1 << 3,            // number 类型
    Boolean = 1 << 4,           // boolean 类型
    Void = 1 << 5,              // void 类型
    Undefined = 1 << 6,         // undefined 类型
    Null = 1 << 7,              // null 类型
    Object = 1 << 19,           // 对象类型
    Union = 1 << 22,            // 联合类型
    Intersection = 1 << 23,     // 交叉类型
    // ... 更多标志
}

🏷️ TypeFlags 枚举详解

Flag 描述
Any 1 << 0 任意类型
Unknown 1 << 1 未知类型(类型安全)
String/Number/Boolean 1 << 2-4 原始类型
Union 1 << 22 联合类型 A | B
Intersection 1 << 23 交叉类型 A & B
Conditional 1 << 24 条件类型
IndexedAccess 1 << 27 索引访问类型 T[K]

🔣 Symbol 类

// Symbol 表示命名实体
class Symbol {
    flags: SymbolFlags;         // 符号标志
    escapedName: __String;      // 转义的名称
    declarations?: Declaration[]; // 声明列表
    valueDeclaration?: Declaration; // 值声明
    members?: SymbolTable;      // 成员符号表
    exports?: SymbolTable;      // 导出符号表
    parent?: Symbol;            // 父符号
    exportSymbol?: Symbol;      // 导出符号
}

// 符号标志位
export const enum SymbolFlags {
    Function = 1 << 0,          // 函数
    Class = 1 << 1,             // 类
    Interface = 1 << 2,         // 接口
    Variable = 1 << 3,          // 变量
    Property = 1 << 4,          // 属性
    Method = 1 << 5,            // 方法
    TypeAlias = 1 << 256,       // 类型别名
    // ... 更多标志
}

🏷️ SymbolFlags 枚举详解

声明类型

  • Function - 函数声明
  • Class - 类声明
  • Interface - 接口声明
  • Variable - 变量声明
  • Enum - 枚举声明
  • Module - 模块声明

修饰符

  • Export - 导出符号
  • Static - 静态成员
  • Private - 私有成员
  • Protected - 受保护成员
  • Readonly - 只读
  • Optional - 可选

Symbol 标志组合: 一个 Symbol 可以同时具有多个标志(如 FunctionScopedVariable = Function | Variable)

🔍 TypeChecker 类

// TypeChecker 是类型系统的核心
export interface TypeChecker {
    // 获取类型
    getTypeOfSymbol(symbol: Symbol): Type;
    getDeclaredTypeOfSymbol(symbol: Symbol): Type;
    getTypeOfTypeNode(node: TypeNode): Type;
    
    // 类型检查
    isAssignableTo(source: Type, target: Type): boolean;
    isSubtypeOf(source: Type, target: Type): boolean;
    
    // 符号解析
    getSymbol(node: Node): Symbol | undefined;
    getAliasedSymbol(symbol: Symbol): Symbol;
    
    // 类型推断
    getContextualType(node: Expression): Type;
    getNon contextualType(node: Expression): Type;
}

⚡ TypeChecker 核心方法

方法 功能 使用场景
getTypeAtLocation 获取节点类型 IDE 悬停提示
checkTypeRelatedTo 类型兼容性检查 赋值检查
getResolvedSignature 解析函数签名 函数调用检查
inferTypes 类型推断 泛型实例化
getApparentType 获取显式类型 类型显示
getWidenedType 类型拓宽 字面量类型

🌳 Node 体系

// Node 是 AST 的基础
export interface Node {
    kind: SyntaxKind;           // 节点类型
    flags: NodeFlags;           // 节点标志
    parent: Node;               // 父节点
    pos: number;                // 起始位置
    end: number;                // 结束位置
    modifiers?: Modifier[];     // 修饰符
    symbol?: Symbol;            // 关联符号
}

// SyntaxKind 枚举(部分)
export const enum SyntaxKind {
    Identifier,                 // 标识符
    StringLiteral,              // 字符串字面量
    NumericLiteral,             // 数字字面量
    BinaryExpression,           // 二元表达式
    CallExpression,             // 调用表达式
    FunctionDeclaration,        // 函数声明
    ClassDeclaration,           // 类声明
    InterfaceDeclaration,       // 接口声明
    TypeReference,              // 类型引用
    // ... 超过 300 种节点类型
}

🏷️ NodeFlags 枚举

作用域标志

  • Let - let 声明
  • Const - const 声明
  • Using - using 声明
  • NestedNamespace - 嵌套命名空间

解析上下文

  • YieldContext - yield 上下文
  • AwaitContext - await 上下文
  • JavaScriptFile - JS 文件

可达性标志

  • HasImplicitReturn - 隐式返回
  • HasExplicitReturn - 显式返回
  • Unreachable - 不可达代码

其他标志

  • Synthesized - 合成节点
  • OptionalChain - 可选链
  • JSDoc - JSDoc 注释

✍️ Signature 接口

// Signature 表示函数/构造器签名
export interface Signature {
    declaration: SignatureDeclaration;  // 声明节点
    typeParameters?: readonly TypeParameter[]; // 类型参数
    parameters: readonly Symbol[];      // 参数列表
    thisParameter?: Symbol;             // this 参数
    resolvedReturnType?: Type;          // 返回类型
    minArgumentCount: number;           // 最小参数数
    hasRestParameter: boolean;          // 是否有剩余参数
    flags: SignatureFlags;              // 签名标志
}

// 签名类型
export const enum SignatureKind {
    Call,                       // 调用签名
    Construct,                  // 构造签名
}

🧩 InferenceContext

// 类型推断上下文
interface InferenceContext {
    typeParameters: readonly TypeParameter[]; // 待推断类型参数
    inferredTypes: Type[];            // 推断结果
    inferTypeArgs(type: Type): void;  // 推断类型参数
    inferencePriority: InferencePriority; // 推断优先级
    inferenceFlags: InferenceFlags;   // 推断标志
}

// 推断优先级
export const enum InferencePriority {
    None = 0,
    NakedTypeVariable = 1 << 0,     // 裸类型变量
    MappedType = 1 << 1,            // 映射类型
    ReturnType = 1 << 2,            // 返回类型
    LiteralKeyof = 1 << 3,          // 字面量 keyof
    NoConstraints = 1 << 4,         // 无约束
}

🔀 FlowNode 控制流

// FlowNode 用于控制流分析
export interface FlowNode {
    flags: FlowFlags;            // 流标志
    id: number;                  // 唯一 ID
    node?: Node;                 // 关联节点
    antecedent?: FlowNode | FlowNode[]; // 前驱节点
}

// 控制流标志
export const enum FlowFlags {
    Start = 1 << 0,              // 起始节点
    BranchLabel = 1 << 1,        // 分支标签
    LoopLabel = 1 << 2,          // 循环标签
    Assignment = 1 << 3,         // 赋值
    Condition = 1 << 4,          // 条件
    Call = 1 << 5,               // 函数调用
    Unreachable = 1 << 8,        // 不可达
}

🔧 createTypeChecker

// checker.ts - 创建类型检查器
export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
    // 核心状态变量
    var typeCount = 0;
    var symbolCount = 0;
    var instantiationDepth = 0;
    var currentNode: Node | undefined;
    
    // 全局符号
    var globals = createSymbolTable();
    var undefinedSymbol = createSymbol(SymbolFlags.Property, "undefined");
    
    // 核心 API
    return {
        getTypeOfSymbol,
        getTypeAtLocation,
        checkTypeRelatedTo,
        // ... 更多方法
    };
}

📊 getTypeOfExpression

// 获取表达式的类型
function getTypeOfExpression(
    node: Expression, 
    checkMode: CheckMode
): Type {
    // 1. 检查缓存
    const cached = getCachedType(node);
    if (cached) return cached;
    
    // 2. 根据节点类型分发
    switch (node.kind) {
        case SyntaxKind.Identifier:
            return getTypeOfIdentifier(node);
        case SyntaxKind.CallExpression:
            return checkCallExpression(node);
        case SyntaxKind.BinaryExpression:
            return checkBinaryExpression(node);
        // ... 更多情况
    }
    
    // 3. 缓存结果
    return cacheType(node, result);
}

🔗 checkTypeRelatedTo

// 检查类型兼容性(核心算法)
function checkTypeRelatedTo(
    source: Type,
    target: Type,
    relation: Relation,
    errorNode?: Node
): boolean {
    // 1. 快速路径:相同类型
    if (source === target) return true;
    
    // 2. Any 类型特殊处理
    if (source.flags & TypeFlags.Any || target.flags & TypeFlags.Any) {
        return true;
    }
    
    // 3. 结构化类型检查
    if (isObjectLikeType(source) && isObjectLikeType(target)) {
        return checkObjectRelatedTo(source, target, relation);
    }
    
    // 4. 联合/交叉类型处理
    if (source.flags & TypeFlags.Union) {
        return every(source.types, t => 
            checkTypeRelatedTo(t, target, relation));
    }
    
    // ... 更多检查逻辑
}

🎯 inferTypes

// 类型推断核心算法
function inferTypes(
    context: InferenceContext,
    source: Type,
    target: Type
): void {
    // 1. 获取类型参数
    const typeParameters = context.typeParameters;
    
    // 2. 递归推断
    for (let i = 0; i < typeParameters.length; i++) {
        const typeParam = typeParameters[i];
        
        // 从源类型推断目标类型参数
        inferFromTypes(context, source, target, typeParam);
    }
    
    // 3. 解析推断结果
    for (let i = 0; i < typeParameters.length; i++) {
        if (!context.inferredTypes[i]) {
            // 使用约束作为默认值
            context.inferredTypes[i] = getConstraint(typeParameters[i]);
        }
    }
}

🔄 instantiateType

// 泛型类型实例化
function instantiateType(
    type: Type,
    mapper: TypeMapper
): Type {
    // 1. 检查是否需要实例化
    if (!needsInstantiation(type, mapper)) {
        return type;
    }
    
    // 2. 创建实例化类型
    const result = createType(TypeFlags.Instantiable);
    
    // 3. 映射类型参数
    if (type.flags & TypeFlags.Object) {
        result.objectType = type.objectType;
        result.typeArguments = map(type.typeArguments, t => 
            instantiateType(t, mapper));
    }
    
    // 4. 缓存并返回
    return cacheInstantiatedType(type, mapper, result);
}

👁️ getApparentType

// 获取显式类型(处理原始类型)
function getApparentType(type: Type): Type {
    // 1. 原始类型包装
    if (type.flags & TypeFlags.String) {
        return getGlobalType("String");
    }
    if (type.flags & TypeFlags.Number) {
        return getGlobalType("Number");
    }
    if (type.flags & TypeFlags.Boolean) {
        return getGlobalType("Boolean");
    }
    
    // 2. 已经是对象类型
    if (type.flags & TypeFlags.Object) {
        return type;
    }
    
    // 3. 联合类型处理
    if (type.flags & TypeFlags.Union) {
        return mapType(type, getApparentType);
    }
    
    return type;
}

🧠 类型推断算法

TypeScript 使用多种策略进行类型推断:

自下而上推断

  • 从表达式推断类型
  • 字面量 → 基础类型
  • 函数调用 → 返回类型

上下文推断

  • 根据使用位置推断
  • 回调函数参数类型
  • 对象字面量属性

最佳公共类型

  • 数组元素类型
  • 联合类型收窄
  • 返回语句分析

控制流分析

  • 类型守卫收窄
  • 赋值分析
  • 条件分支分析

⚖️ 类型兼容性检查

TypeScript 使用结构化类型系统(鸭子类型):

// 结构化类型检查规则:
// 1. 成员兼容性
if (targetHasProperty && !sourceHasProperty) {
    return false; // 不兼容
}

// 2. 函数参数双向协变
if (strictFunctionTypes) {
    // 严格模式:参数逆变
    return isSubtypeOf(targetParam, sourceParam);
} else {
    // 宽松模式:参数双向协变
    return isRelatedTo(targetParam, sourceParam);
}

// 3. 返回类型协变
return isSubtypeOf(sourceReturnType, targetReturnType);

🔄 泛型实例化流程

// 泛型实例化流程图
┌──────────────────────────────────────┐
│ function identity<T>(arg: T): T     │
│ 泛型声明                              │
└───────────────┬──────────────────────┘
                ↓
┌──────────────────────────────────────┐
│ identity<string>("hello")            │
│ 显式指定类型参数                      │
└───────────────┬──────────────────────┘
                ↓
┌──────────────────────────────────────┐
│ instantiateType(identity, {          │
│   T → string                         │
│ })                                   │
│ 类型映射                              │
└───────────────┬──────────────────────┘
                ↓
┌──────────────────────────────────────┐
│ function identity(arg: string): string│
│ 实例化结果                            │
└──────────────────────────────────────┘

❓ 条件类型求值

// 条件类型求值算法
function resolveConditionalType(type: ConditionalType): Type {
    // 1. 检查 extends 子句
    const checkType = type.checkType;
    const extendsType = type.extendsType;
    
    // 2. 类型关系检查
    const isAssignable = checkTypeRelatedTo(
        checkType, 
        extendsType,
        relation
    );
    
    // 3. 选择结果类型
    if (isAssignable) {
        // true 分支:推断类型参数
        const inferred = inferFromExtends(checkType, extendsType);
        return instantiateType(type.trueType, inferred);
    } else {
        // false 分支
        return type.falseType;
    }
}

// 示例:T extends U ? X : Y

🏭 设计模式:工厂模式

// TypeScript 编译器大量使用工厂模式

// 1. 对象分配器工厂
export const objectAllocator = {
    getSymbolConstructor: () => Symbol,
    getTypeConstructor: () => Type,
    getSignatureConstructor: () => Signature,
};

// 2. 节点工厂
export const factory = {
    createIdentifier(text: string): Identifier,
    createFunctionDeclaration(...): FunctionDeclaration,
    createClassDeclaration(...): ClassDeclaration,
    // ... 超过 200 个工厂方法
};

// 3. 类型检查器工厂
export function createTypeChecker(host: TypeCheckerHost): TypeChecker;

👀 设计模式:访问者模式

// AST 遍历使用访问者模式

// forEachChild 实现
export function forEachChild(
    node: Node, 
    cbNode: (node: Node) => T | undefined
): T | undefined {
    // 根据节点类型选择子节点
    switch (node.kind) {
        case SyntaxKind.BinaryExpression:
            const binary = node as BinaryExpression;
            return cbNode(binary.left) || 
                   cbNode(binary.right) ||
                   cbNode(binary.operatorToken);
        case SyntaxKind.CallExpression:
            const call = node as CallExpression;
            return cbNode(call.expression) ||
                   forEachChild(call.arguments, cbNode);
        // ... 处理所有节点类型
    }
}

💾 设计模式:缓存模式

// 类型系统大量使用缓存

// 1. 节点链接缓存
interface NodeLinks {
    flags: NodeCheckFlags;
    resolvedType?: Type;         // 缓存类型
    resolvedSignature?: Signature; // 缓存签名
}

// 2. 符号链接缓存
interface SymbolLinks {
    type?: Type;                 // 缓存符号类型
    declaredType?: Type;         // 缓存声明类型
    resolvedTypeArguments?: Type[]; // 缓存类型参数
}

// 3. 全局类型缓存
const cachedTypes = new Map();

function getCachedType(key: string): Type | undefined {
    return cachedTypes.get(key);
}

⏳ 设计模式:延迟求值

// 类型系统使用延迟求值提高性能

// 1. 延迟诊断
var deferredDiagnosticsCallbacks: (() => void)[] = [];

function addLazyDiagnostic(callback: () => void) {
    deferredDiagnosticsCallbacks.push(callback);
}

// 2. 延迟类型解析
interface DeferredTypeReference {
    type: Type;
    node: TypeReferenceNode;
    resolve(): Type;
}

// 3. 按需检查
function getTypeOfSymbol(symbol: Symbol): Type {
    // 仅在需要时计算
    if (!symbolLinks.type) {
        symbolLinks.type = computeTypeOfSymbol(symbol);
    }
    return symbolLinks.type;
}

📐 类型系统 UML 类图

┌──────────┐     ┌──────────┐     ┌──────────┐
│   Node   │────▶│  Symbol  │────▶│   Type   │
└──────────┘     └──────────┘     └──────────┘
     │                │                │
     ▼                ▼                ▼
┌──────────┐     ┌──────────┐     ┌──────────┐
│  Parser  │     │  Binder  │     │ Checker  │
└──────────┘     └──────────┘     └──────────┘

Type 子类:
┌──────────────┬──────────────┬──────────────┐
│  ObjectType  │  UnionType   │ Conditional  │
├──────────────┼──────────────┼──────────────┤
│ InterfaceType│IntersectionT │  TupleType   │
├──────────────┼──────────────┼──────────────┤
│  TypeRef     │ TypeParameter│ IndexedAccess│
└──────────────┴──────────────┴──────────────┘

🔄 编译流程图

Source Code (TS)
      │
      ▼
┌─────────────┐
│   Scanner   │ 词法分析
└──────┬──────┘
       │ Token Stream
       ▼
┌─────────────┐
│   Parser    │ 语法分析
└──────┬──────┘
       │ AST
       ▼
┌─────────────┐
│   Binder    │ 符号绑定
└──────┬──────┘
       │ Symbol Table
       ▼
┌─────────────┐
│  Checker    │ 类型检查 ⭐
└──────┬──────┘
       │ Type Information
       ▼
┌─────────────┐
│   Emitter   │ 代码生成
└──────┬──────┘
       │
       ▼
  JavaScript

🎯 类型推断流程

Expression Node
       │
       ▼
getTypeOfExpression(node)
       │
       ├─── Identifier?
       │         │
       │         ▼
       │    getSymbol() → getTypeOfSymbol()
       │
       ├─── CallExpression?
       │         │
       │         ▼
       │    resolveSignature() → getReturnType()
       │
       ├─── BinaryExpression?
       │         │
       │         ▼
       │    checkBinaryExpression()
       │
       └─── Literal?
                 │
                 ▼
            getLiteralType()

       │
       ▼
  Cache Result

⚖️ 类型关系检查流程

checkTypeRelatedTo(source, target)
              │
              ├── source === target? ──→ true
              │
              ├── any type? ──→ true
              │
              ├── Union type?
              │        │
              │        ▼
              │   every(types, t => check(t, target))
              │
              ├── Intersection type?
              │        │
              │        ▼
              │   some(types, t => check(t, target))
              │
              └── Object type?
                       │
                       ▼
                  checkStructuralType()
                       │
                       ├── check properties
                       ├── check call signatures
                       └── check construct signatures

🔀 控制流分析

TypeScript 使用控制流分析进行类型收窄:

// 控制流图构建
function bindFlowNode(node: Node) {
    // 1. 条件分支
    if (isIfStatement(node)) {
        const trueFlow = createFlowCondition(...);
        const falseFlow = createFlowCondition(...);
        // 合并分支
        currentFlow = createFlowLabel([trueFlow, falseFlow]);
    }
    
    // 2. 赋值分析
    if (isAssignment(node)) {
        currentFlow = createFlowAssignment(
            currentFlow, 
            node.left, 
            getTypeOfExpression(node.right)
        );
    }
    
    // 3. 类型守卫
    if (isTypeGuard(node)) {
        currentFlow = createFlowCondition(
            currentFlow, 
            node, 
            /*truthy*/ true
        );
    }
}

⚡ 性能优化策略

缓存策略

  • 节点类型缓存
  • 符号类型缓存
  • 类型关系缓存
  • 签名解析缓存

延迟计算

  • 按需类型检查
  • 延迟诊断生成
  • 惰性符号解析

结构优化

  • 单例类型复用
  • 类型规范化
  • 联合类型简化

增量编译

  • 增量类型检查
  • 程序重用
  • 引用追踪

💾 类型缓存机制

// 多层缓存架构

// 1. 节点级别缓存
node.links = {
    type: Type,           // 缓存的类型
    flags: NodeCheckFlags // 检查标志
};

// 2. 符号级别缓存
symbol.links = {
    type: Type,           // 符号类型
    declaredType: Type,   // 声明类型
    resolvedTypeArguments: Type[]
};

// 3. 全局类型缓存
const globalTypeCache = new Map();

// 4. 实例化缓存
const instantiationCache = new Map<
    Type, 
    Map
>();

🔄 增量编译优化

增量编译通过复用先前编译结果提高性能:

// .tsbuildinfo 文件结构
interface TsBuildInfo {
    program: ProgramBuildInfo;
    typeCheckerDiagnostics: Diagnostic[];
    version: string;
}

// 增量检查逻辑
function incrementalCheck(oldProgram: Program, newSourceFile: SourceFile) {
    // 1. 复用未改变的文件
    const reusedFiles = oldProgram.getSourceFiles()
        .filter(f => !hasChanged(f));
    
    // 2. 重新检查改变的文件
    const changedFiles = [newSourceFile];
    
    // 3. 复用类型检查器
    const checker = oldProgram.getTypeChecker();
    
    // 4. 增量更新
    return createIncrementalProgram(reusedFiles, changedFiles);
}

🧠 内存管理

内存优化技术

  • 对象池复用
  • 弱引用缓存
  • 符号表优化
  • AST 节点共享

内存统计

  • typeCount: 类型数量
  • symbolCount: 符号数量
  • instantiationCount: 实例化次数

大型项目优化

  • 项目引用分割
  • 惰性加载源文件
  • 内存中保留最少信息

编译选项

  • skipLibCheck
  • incremental
  • assumeChangesOnlyAffectDirectDependencies

✅ 类型设计最佳实践

类型定义

  • 优先使用 interface
  • 避免 any,使用 unknown
  • 使用字面量类型
  • 善用类型推断

泛型设计

  • 约束类型参数
  • 使用默认类型参数
  • 避免过度泛型化

类型复用

  • 使用工具类型
  • 创建可复用类型工具
  • 模块化类型定义

类型安全

  • 启用 strict 模式
  • 使用类型守卫
  • 避免类型断言

❌ 常见反模式

避免以下类型系统反模式:

// ❌ 反模式:滥用 any
function processData(data: any) { ... }

// ✅ 正确:使用 unknown + 类型守卫
function processData(data: unknown) {
    if (typeof data === 'string') { ... }
}

// ❌ 反模式:过度类型断言
const obj = {} as MyInterface;

// ✅ 正确:提供完整类型信息
const obj: MyInterface = { prop: 'value' };

// ❌ 反模式:忽略 null/undefined
function getName(user: User): string {
    return user.name; // 可能 undefined
}

// ✅ 正确:处理 null/undefined
function getName(user: User): string {
    return user.name ?? 'Unknown';
}

🎭 类型体操技巧

// 高级类型操作技巧

// 1. 递归类型
type DeepPartial<T> = {
    [P in keyof T]?: T[P] extends object 
        ? DeepPartial<T[P]> 
        : T[P];
};

// 2. 条件类型分发
type NonNullable<T> = T extends null | undefined ? never : T;

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

// 4. 模板字面量类型
type EventName<T extends string> = `on${Capitalize<T>}`;

// 5. infer 关键字
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

🔍 调试技巧

编译器调试

  • 使用 tsc --traceResolution
  • 启用 --diagnostics
  • 使用 --explainFiles
  • 检查 .tsbuildinfo

类型调试

  • 悬停查看类型
  • 使用类型别名
  • 工具类型展开

性能分析

  • tsc --extendedDiagnostics
  • 分析编译时间
  • 检查类型复杂度

常见问题

  • 循环依赖
  • 类型实例化过深
  • 大型联合类型

🌍 与其他语言对比

特性 TypeScript Flow Haskell
类型系统 结构化 结构化 名义化
类型推断 局部 局部 全局
泛型
高阶类型
运行时
渐进式

🚀 未来发展趋势

近期路线图

  • 改进类型推断
  • 更好的错误消息
  • 性能优化
  • 装饰器标准化

长期目标

  • 更智能的类型推断
  • 部分类型求值
  • 类型级别的编程

社区提案

  • 高阶类型 (HKT)
  • 模式匹配类型
  • 宏系统
  • 运行时类型

工具链演进

  • 更快的编译器
  • 更好的 LSP
  • 类型共享

📚 总结与扩展阅读

核心要点回顾:

类型系统核心

  • Type / Symbol / Node 三位一体
  • TypeChecker 是核心引擎
  • 结构化类型系统
  • 控制流分析增强

扩展阅读

  • TypeScript GitHub
  • TypeScript 设计会议笔记
  • TypeScript 编译器源码
  • TypeScript 语言规范

50 页技术深度解析完成!

💙 TypeScript 类型系统 - 让 JavaScript 更安全