Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第8章:类型系统进阶

第8章:类型系统进阶

类型保护与类型收缩

概述

类型保护(Type Guards)和类型收缩(Type Narrowing)是 TypeScript 中用于在特定代码块内缩小变量类型范围的重要机制。它们通过条件判断或特定语法,帮助编译器推断更精确的类型,从而增强类型安全性并减少运行时错误。


1. 常见的类型保护方式

(1) typeof 类型保护

function printValue(value: string | number) {
    if (typeof value === "string") {
        console.log(value.toUpperCase()); // 此处 value 被推断为 string
    } else {
        console.log(value.toFixed(2)); // 此处 value 被推断为 number
    }
}

(2) instanceof 类型保护

class Animal { move() {} }
class Bird extends Animal { fly() {} }

function handleAnimal(animal: Animal) {
    if (animal instanceof Bird) {
        animal.fly(); // 此处 animal 被推断为 Bird
    }
}

(3) 自定义类型谓词(User-Defined Type Guards)

interface Cat { meow(): void }
interface Dog { bark(): void }

function isCat(pet: Cat | Dog): pet is Cat {
    return (pet as Cat).meow !== undefined;
}

function petSound(pet: Cat | Dog) {
    if (isCat(pet)) {
        pet.meow(); // 类型被收缩为 Cat
    }
}

2. 类型收缩的典型场景

(1) 真值收缩(Truthiness Narrowing)

function processValue(value?: string) {
    if (value) {
        console.log(value.trim()); // value 被收缩为 string(排除 null/undefined/"")
    }
}

(2) 相等性收缩(Equality Narrowing)

function example(x: string | number, y: string | boolean) {
    if (x === y) {
        // 此处 x 和 y 都被收缩为 string
    }
}

(3) in 操作符收缩

interface Admin { role: string }
interface User { email: string }

function redirect(entity: Admin | User) {
    if ("role" in entity) {
        console.log("Admin:", entity.role); // 收缩为 Admin
    }
}

3. 判别式联合(Discriminated Unions)

通过共享字面量属性(判别式)实现精确类型收缩:

type Shape =
    | { kind: "circle"; radius: number }
    | { kind: "square"; side: number };

function getArea(shape: Shape) {
    switch (shape.kind) {
        case "circle":
            return Math.PI * shape.radius ** 2; // 精确识别为 circle 类型
        case "square":
            return shape.side ** 2;
    }
}

4. 注意事项

  1. 类型断言 vs 类型保护
    避免过度使用 as 断言,优先让类型保护自动推断。
  2. 复杂联合类型
    当处理多层嵌套的联合类型时,可能需要组合多种保护方式。
  3. 性能影响
    过多的类型保护可能增加编译时间,但不会影响运行时性能。

示例:综合应用

function processInput(input: unknown) {
    if (typeof input === "string") {
        console.log(input.toUpperCase());
    } else if (Array.isArray(input)) {
        console.log(input.length);
    } else if (input && typeof input === "object" && "id" in input) {
        console.log((input as { id: string }).id);
    }
}

通过合理使用类型保护与收缩,可以显著提升代码的类型安全性和可维护性。

Last Updated:: 3/27/25, 10:50 AM