目录
1. 条件类型的语法与基本原理
2. 分布式条件类型(Distributive Conditional Types)
3. 类型过滤与提取工具
提取函数类型
排除某些类型(类似 Exclude
提取某些类型(类似 Extract
过滤 null/undefined(类似 NonNullable
4. infer:在条件类型中推断类型
提取函数返回值类型(类似 ReturnType
提取数组元素类型(类似 ElementType
提取 Promise 的解析值(类似 Awaited
5. 实用高级模式
1. 深度只读(DeepReadonly)
2. 函数重载解析(简化签名)
3. 联合转交叉类型(高级技巧)
6. 常见陷阱与注意事项
总结
首页 web前端 js教程 在打字稿中的高级条件类型

在打字稿中的高级条件类型

Aug 04, 2025 am 06:32 AM
java 编程

TypeScript 的高级条件类型通过 T extends U ? X : Y 语法实现类型间的逻辑判断,其核心能力体现在分布式条件类型、infer 类型推断和复杂类型工具的构建。1. 条件类型在裸类型参数上具有分布性,能自动对联合类型拆分处理,如 ToArray 得到 string[] | number[]。2. 利用分布性可构建过滤与提取工具:Exclude 通过 T extends U ? never : T 排除类型,Extract 通过 T extends U ? T : never 提取共性,NonNullable 过滤 null/undefined。3. infer 关键字用于在条件类型中模式匹配并提取子类型,如 ReturnType 提取函数返回值,ElementType 获取数组元素类型,UnwrapPromise 解包 Promise 内容。4. 高级模式包括 DeepReadonly 实现对象深度只读,FirstParam 提取函数参数类型,UnionToIntersection 将联合类型转为交叉类型以合并对象结构。5. 注意 never 在联合类型中被自动忽略、条件类型的惰性求值行为,以及 any 导致的保守推导结果。掌握这些机制可实现类型级逻辑运算,构建安全高效的泛型抽象,最终提升类型系统的表达力与代码可靠性。

Advanced Conditional Types in TypeScript

TypeScript 的高级条件类型(Advanced Conditional Types)是类型系统中最强大、最灵活的部分之一。它们允许你根据类型之间的关系动态生成新类型,常用于构建复杂的类型工具、类型守卫和泛型抽象。理解这些特性,能让你写出更安全、更智能的类型代码。

Advanced Conditional Types in TypeScript

下面是一些关键概念和实用技巧,带你深入掌握高级条件类型。


1. 条件类型的语法与基本原理

条件类型的语法类似于 JavaScript 的三元运算符:

Advanced Conditional Types in TypeScript
T extends U ? X : Y

意思是:如果类型 T 可以赋值给 U,那么结果类型是 X,否则是 Y

例子:

Advanced Conditional Types in TypeScript
type IsString<T> = T extends string ? true : false;

type A = IsString<'hello'>;  // true
type B = IsString<42>;       // false

这看起来简单,但它的真正威力体现在与泛型、联合类型和分布式条件类型结合时。


2. 分布式条件类型(Distributive Conditional Types)

当条件类型作用于泛型,并且该泛型出现在 extends 左边时,TypeScript 会自动对联合类型进行“分布”处理。

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

如果你传入 string | number,TypeScript 会将其拆开:

ToArray<string | number> 
// 等价于:
// (string extends any ? string[] : never) | (number extends any ? number[] : never)
// 结果是:string[] | number[]

✅ 这种“自动分发”只发生在裸类型参数(naked type parameter)上。如果你把 T 包在元组或对象中,比如 [T] extends [any],分布性就会关闭。

用途: 常用于将联合类型中的每一项单独处理,比如提取/过滤类型。


3. 类型过滤与提取工具

利用分布式条件类型,我们可以构建强大的类型工具。

提取函数类型

type GetFunction<T> = T extends (...args: any[]) => any ? T : never;

type FuncsOnly = GetFunction<string | () => number | number | (s: string) => void>;
// 结果:() => number | (s: string) => void

排除某些类型(类似 Exclude

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

type NoString = Exclude<string | number | boolean, string>; // number | boolean

TypeScript 内置的 Exclude<T, U> 就是这么实现的。

提取某些类型(类似 Extract

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

type OnlyStringOrNumber = Extract<string | number | boolean, string | number>; // string | number

过滤 null/undefined(类似 NonNullable

type NonNullable<T> = T extends null | undefined ? never : T;

type A = NonNullable<string | null | undefined>; // string

4. infer:在条件类型中推断类型

infer 是条件类型中用于“模式匹配”和提取子类型的利器。

提取函数返回值类型(类似 ReturnType

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

type R = ReturnType<() => string>; // string

提取数组元素类型(类似 ElementType

type ElementType<T> = T extends (infer U)[] ? U : never;

type Item = ElementType<number[]>; // number
type Item2 = ElementType<string[]>; // string

提取 Promise 的解析值(类似 Awaited

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

type Value = UnwrapPromise<Promise<string>>; // string
type Value2 = UnwrapPromise<number>;         // number

infer 可以出现在元组、函数参数、返回值、对象属性等位置,实现复杂的类型解构。


5. 实用高级模式

1. 深度只读(DeepReadonly)

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

这里用条件类型判断字段是否是对象,避免对函数递归。

2. 函数重载解析(简化签名)

type FirstParam<F> = F extends (arg: infer P) => any ? P : never;

type ID = FirstParam<(id: string) => void>; // string

3. 联合转交叉类型(高级技巧)

有时你想把 string | number 转成 string & number(虽然结果是 never),但更常见的是用于函数参数的“逆变”处理。

type UnionToIntersection<U> = 
  (U extends any ? (k: U) => void : never) extends (k: infer I) => void 
    ? I 
    : never;

type T = UnionToIntersection<{a:1} | {b:2}>; // {a:1} & {b:2}

这个技巧常用于类型推导中“合并”多个类型。


6. 常见陷阱与注意事项

  • never 在联合类型中会被忽略

    type T = string | never; // 等价于 string

    所以 Exclude 中用 never 来“过滤掉”类型是有效的。

  • 条件类型是惰性的

    条件类型只有在被实例化时才会计算。例如:

    type Foo<T> = T extends string ? string : number;
    type A = Foo<any>; // type is string | number

    因为 anystring 的关系是“模糊的”,TypeScript 会保守地返回 string | number

  • never 的特殊行为

    never 是所有类型的子类型,所以在条件类型中:

    type T = never extends string ? true : false; // true

    但这不意味着 never 是字符串,而是类型系统规则如此。


    总结

    高级条件类型是 TypeScript 类型编程的核心。结合 extendsinfer 和分布式行为,你可以:

    • 过滤、提取、转换类型
    • 实现类型级“逻辑判断”
    • 构建复杂的泛型工具(如 PickOmitReturnType 等)

    虽然一开始看起来像魔法,但只要理解了“类型是集合”、“条件类型是集合判断”这一思想,就能逐步掌握。

    基本上就这些。多写、多试,你会发现类型系统比想象中更强大。

    以上是在打字稿中的高级条件类型的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

PHP教程
1598
276
Java的僵局是什么,您如何防止它? Java的僵局是什么,您如何防止它? Aug 23, 2025 pm 12:55 PM

AdeadlockinJavaoccurswhentwoormorethreadsareblockedforever,eachwaitingforaresourceheldbytheother,typicallyduetocircularwaitcausedbyinconsistentlockordering;thiscanbepreventedbybreakingoneofthefournecessaryconditions—mutualexclusion,holdandwait,nopree

您目前尚未使用附上的显示器[固定] 您目前尚未使用附上的显示器[固定] Aug 19, 2025 am 12:12 AM

Ifyousee"YouarenotusingadisplayattachedtoanNVIDIAGPU,"ensureyourmonitorisconnectedtotheNVIDIAGPUport,configuredisplaysettingsinNVIDIAControlPanel,updatedriversusingDDUandcleaninstall,andsettheprimaryGPUtodiscreteinBIOS/UEFI.Restartaftereach

如何在Java中使用可选的? 如何在Java中使用可选的? Aug 22, 2025 am 10:27 AM

useoptional.empty(),可选of(),andoptional.ofnullable()

使用Micronaut构建云原生爪哇应用 使用Micronaut构建云原生爪哇应用 Aug 20, 2025 am 01:53 AM

Micronautisidealforbuildingcloud-nativeJavaapplicationsduetoitslowmemoryfootprint,faststartuptimes,andcompile-timedependencyinjection,makingitsuperiortotraditionalframeworkslikeSpringBootformicroservices,containers,andserverlessenvironments.1.Microna

用于安全编码的Java加密体系结构(JCA) 用于安全编码的Java加密体系结构(JCA) Aug 23, 2025 pm 01:20 PM

理解JCA核心组件如MessageDigest、Cipher、KeyGenerator、SecureRandom、Signature、KeyStore等,它们通过提供者机制实现算法;2.使用SHA-256/SHA-512、AES(256位密钥,GCM模式)、RSA(2048位以上)和SecureRandom等强算法与参数;3.避免硬编码密钥,使用KeyStore管理密钥,并通过PBKDF2等安全派生密码生成密钥;4.禁用ECB模式,采用GCM等认证加密模式,每次加密使用唯一随机IV,并及时清除敏

Java持续使用弹簧数据JPA和Hibernate Java持续使用弹簧数据JPA和Hibernate Aug 22, 2025 am 07:52 AM

SpringDataJPA与Hibernate协同工作的核心是:1.JPA为规范,Hibernate为实现,SpringDataJPA封装简化DAO开发;2.实体类通过@Entity、@Id、@Column等注解映射数据库结构;3.Repository接口继承JpaRepository可自动实现CRUD及命名查询方法;4.复杂查询使用@Query注解支持JPQL或原生SQL;5.SpringBoot中通过添加starter依赖并配置数据源、JPA属性完成集成;6.事务由@Transactiona

修复:Windows显示'客户不持有所需的特权” 修复:Windows显示'客户不持有所需的特权” Aug 20, 2025 pm 12:02 PM

runtheapplicationorcommandasadministratorByright-clickingandSelecting“ runasAdministrator” toensureeleeleeleeleviledprivilegesareAreDranted.2.checkuseracccountcontontrol(uac)uac)

如何在Java中使用模式和匹配器类? 如何在Java中使用模式和匹配器类? Aug 22, 2025 am 09:57 AM

Pattern类用于编译正则表达式,Matcher类用于在字符串上执行匹配操作,二者结合可实现文本搜索、匹配和替换;首先通过Pattern.compile()创建模式对象,再调用其matcher()方法生成Matcher实例,接着使用matches()判断全字符串匹配、find()查找子序列、replaceAll()或replaceFirst()进行替换,若正则包含捕获组,可通过group(n)获取第n组内容,实际应用中应避免重复编译模式、注意特殊字符转义并根据需要使用匹配模式标志,最终实现高效

See all articles