当前位置: 首页 > news >正文

TypeScript extends 全面解析

TypeScript extends 全面解析


在这里插入图片描述

一、extends 的多重身份解析

1.1 TypeScript 中的 extends 全景图

extends 是 TypeScript 中最为核心的关键字之一,其功能覆盖类型系统的多个层面:

extends
类与接口继承
泛型约束
条件类型
类型推断
类型守卫
映射类型修饰

1.2 类型系统中的约束层次

约束级别描述典型语法
继承约束类/接口的继承关系class A extends B
泛型约束限制类型参数范围<T extends SomeType>
条件约束类型条件判断T extends U ? X : Y
推断约束类型推断时的条件限制infer U extends SomeType
映射约束映射类型中的属性修饰[K in keyof T as ...]

二、类与接口继承的深度剖析

2.1 类继承机制

基础继承示例

class Animal {
    move() {
        console.log("Moving...");
    }
}

class Dog extends Animal {
    bark() {
        console.log("Woof!");
    }
}

const myDog = new Dog();
myDog.move(); // 继承方法
myDog.bark(); // 自有方法

继承的三层内涵

  1. 方法继承:获得父类的所有公共方法
  2. 属性继承:自动包含父类的公共属性
  3. 类型兼容:子类实例可赋值给父类类型

2.2 接口继承特性

多继承示例

interface Shape {
    color: string;
}

interface Size {
    width: number;
    height: number;
}

interface Rectangle extends Shape, Size {
    borderWidth: number;
}

const rect: Rectangle = {
    color: "blue",
    width: 100,
    height: 50,
    borderWidth: 2
};

接口继承特点

  • 支持多重继承
  • 合并多个接口类型
  • 可继承类型别名(Type Alias)
  • 允许覆盖父接口属性(需保持兼容)

2.3 继承与实现的区别

extends vs implements 对比:

特性extendsimplements
适用对象类继承、接口继承类实现接口
多重性类单继承,接口多继承可多实现
方法实现自动继承父类实现必须显式实现所有成员
类型检查结构兼容即可严格匹配接口定义
运行时影响影响原型链仅编译时检查

三、泛型约束:类型安全的基石

3.1 基础泛型约束

典型应用场景

interface HasLength {
    length: number;
}

function logLength<T extends HasLength>(arg: T): void {
    console.log(arg.length);
}

logLength("hello");    // 5
logLength([1,2,3]);    // 3
logLength({length: 7}); // 7
// logLength(42);       // 错误:数字没有length属性

3.2 多重约束策略

联合类型约束

function processInput<T extends string | number>(input: T): T {
    // 处理逻辑
    return input;
}

交叉类型约束

interface Name {
    name: string;
}

interface Age {
    age: number;
}

function createPerson<T extends Name & Age>(info: T): T {
    return info;
}

3.3 递归约束模式

树形结构约束示例

interface TreeNode<T> {
    value: T;
    children?: TreeNode<T>[];
}

function traverse<T extends TreeNode<any>>(node: T): void {
    console.log(node.value);
    node.children?.forEach(traverse);
}

四、条件类型:类型逻辑的核心引擎

4.1 基础条件类型

类型过滤示例

type FilterNumber<T> = T extends number ? T : never;

type Numbers = FilterNumber<string | number | boolean>; // number

4.2 分布式条件类型

分布式特性演示

type ToArray<T> = T extends any ? T[] : never;

type StrOrNumArray = ToArray<string | number>; 
// string[] | number[]

禁用分布式特性

type ToArrayNonDist<T> = [T] extends [any] ? T[] : never;

type UnionArray = ToArrayNonDist<string | number>; 
// (string | number)[]

4.3 条件类型推断

类型解构示例

type UnpackPromise<T> = T extends Promise<infer U> ? U : T;

type A = UnpackPromise<Promise<string>>;    // string
type B = UnpackPromise<number>;            // number

递归解包实现

type DeepUnpack<T> = 
    T extends Promise<infer U> 
    ? DeepUnpack<U> 
    : T;

type C = DeepUnpack<Promise<Promise<string>>>; // string

五、高级类型操作中的 extends

5.1 映射类型修饰

只读化转换

type ReadonlyDeep<T> = {
    readonly [K in keyof T]: 
        T[K] extends object ? ReadonlyDeep<T[K]> : T[K];
};

interface Company {
    name: string;
    departments: {
        engineering: string[];
        sales: string[];
    };
}

const readonlyCompany: ReadonlyDeep<Company> = {
    name: "Tech Corp",
    departments: {
        engineering: ["Alice", "Bob"],
        sales: ["Charlie"]
    }
};

// readonlyCompany.departments.engineering.push("Dave"); // 错误

5.2 类型守卫强化

自定义类型守卫

function isStringArray(arr: any[]): arr is string[] {
    return arr.every(item => typeof item === "string");
}

function processArray<T extends any[]>(arr: T): T extends string[] ? string : never {
    return isStringArray(arr) ? arr.join(", ") : undefined!;
}

5.3 模板字面量类型

路径参数匹配

type ExtractParams<Path extends string> = 
    Path extends `${string}:${infer Param}/${infer Rest}`
    ? Param | ExtractParams<Rest>
    : Path extends `${string}:${infer Param}`
    ? Param
    : never;

type Params = ExtractParams<"/user/:id/posts/:postId">; // "id" | "postId"

六、extends 的边界与陷阱

6.1 条件类型中的类型收窄

常见误区示例

type MyExclude<T, U> = T extends U ? never : T;

// 正确使用
type T1 = MyExclude<"a" | "b" | "c", "a">; // "b" | "c"

// 错误预期
type T2 = MyExclude<string | number, number>; // string

分布式特性导致的意外结果

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

6.2 泛型约束的过度限制

不合理的约束示例

interface Animal {
    name: string;
}

interface Dog extends Animal {
    breed: string;
}

function badExample<T extends Animal>(arg: T) {
    // 错误:不能访问子类特有属性
    console.log(arg.breed); 
}

正确解决方案

function goodExample<T extends Dog>(arg: T) {
    console.log(arg.breed); // 正确
}

6.3 循环引用问题

危险的结构定义

interface TreeNode<T extends TreeNode<any>> {
    value: number;
    children: T[];
}

// 会导致无限递归类型检查

安全的重构方案

interface BaseNode {
    value: number;
}

interface TreeNode extends BaseNode {
    children: TreeNode[];
}

九、综合应用:构建类型安全框架

9.1 请求处理管道

类型约束的中间件系统

type Middleware<T extends Context> = (
    context: T,
    next: () => Promise<void>
) => Promise<void>;

class Context {
    // 基础上下文定义
}

class AuthContext extends Context {
    user: User;
}

const authMiddleware: Middleware<AuthContext> = async (ctx, next) => {
    // 身份验证逻辑
    await next();
};

总结

通过本文的全面探讨,我们深入剖析了 extends 关键字的各个方面,从基础的类继承到高级的条件类型操作。extends 的核心价值在于:

  1. 增强类型安全性:通过约束防止无效类型传播
  2. 提升代码抽象能力:创建灵活可复用的类型模式
  3. 实现精确类型操作:支持复杂的类型转换和推断
  4. 构建可维护架构:为大型应用提供可靠的类型基础

在实际开发中,建议遵循以下原则:

  • 渐进式约束:从松到紧逐步增加类型约束
  • 防御式编程:对第三方类型进行适当约束
  • 持续重构:随着需求变化优化类型约束
  • 性能意识:避免过度复杂的类型操作

随着 TypeScript 的持续演进,extends 将继续在类型系统中扮演关键角色。掌握其精髓,将使您的代码兼具灵活性与安全性,在复杂应用开发中游刃有余。

http://www.dtcms.com/a/106884.html

相关文章:

  • work02_1 计算这两个日期之间相隔的天数
  • 手机改了IP地址,定位位置会改变吗?
  • Java面试黄金宝典29
  • 蓝桥备赛指南(13):填空签到题(1-1)
  • 车辆控制解决方案
  • 如何通过安当TDE透明加密实现MySQL数据库加密与解密:应用免改造,字段与整库加密全解析
  • MySQL主从复制(四)
  • WEB安全--文件上传漏洞--其他绕过方式
  • OpenLayers:封装Overlay的方法
  • WASM I/O 2025 | MoonBit获Kotlin核心开发,Golem Cloud CEO高度评价
  • 人工智能赋能管理系统,如何实现智能化决策?
  • 操作系统(中断 异常 陷阱) ─── linux第28课
  • 脑影像分析软件推荐 | JuSpace
  • 【kubernetes】pod拉取镜像的策略
  • 关于SQL子查询的使用策略
  • ​自动化网络架构搜索(Neural Architecture Search,NAS)
  • RNN模型与NLP应用——(9/9)Self-Attention(自注意力机制)
  • 1Panel 面板 宝塔面板 Ubuntu 24.04
  • 叁仟数智指路机器人是否支持远程监控和管理?
  • Rclone同步Linux数据到google云盘
  • 【SQL】MySQL进阶3:Innodb引擎结构,事务与ACID的实现
  • Apifox Helper 与 Swagger3 区别
  • 一个服务器算分布式吗,分布式需要几个服务器
  • 电子企业MES管理系统智能排产与动态调度优化
  • 化工网平台API接口开发实战:从接入到数据解析‌
  • 递归(实践版)
  • 阿里云AI Studio 2.0:拖拽搭建企业级智能客服系统
  • 信息学奥赛一本通 1611:仓库建设 | 洛谷 P2120 [ZJOI2007] 仓库建设
  • Cribl 创建路线Route
  • dubbo RPC协议