提示:本网站现在为维护调试状态

TypeScript 高级类型体操

Choyeon
Choyeon
2026年8月25日 1 分钟阅读 387 阅读
643 字 949 字符 更新于 2026年11月8日
TypeScript 高级类型体操
目录

TypeScript 的类型系统是图灵完备的。这意味着理论上你可以在类型层面完成任何计算。了解这些高级特性,不仅能看懂开源库的类型定义,还能为自己的代码写出精准的类型推导。

核心工具:条件类型 + infer

如果只能掌握一个特性,那必须是条件类型 + infer。它类似类型层面的三元表达式:

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

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

type DeepRequired<T> = T extends object
  ? { [K in keyof T]-?: DeepRequired<T[K]> }
  : T

type PickByType<T, U> = {
  [K in keyof T as T[K] extends U ? K : never]: T[K]
}

type OmitByType<T, U> = {
  [K in keyof T as T[K] extends U ? never : K]: T[K]
}

type PathOf<T, Prefix extends string = ''> = T extends object
  ? {
      [K in keyof T & string]: K extends string
        ?
            | `${Prefix}${K}`
            | PathOf<T[K], `${Prefix}${K}.`>
        : never
    }[keyof T & string]
  : never

type ValueAtPath<T, P extends string> = P extends `${infer K}.${infer Rest}`
  ? K extends keyof T
    ? ValueAtPath<T[K], Rest>
    : never
  : P extends keyof T
  ? T[P]
  : never

type CamelCase<S extends string> = S extends `${infer First}_${infer Rest}`
  ? `${First}${Capitalize<CamelCase<Rest>>}`
  : S

type SnakeCase<S extends string> = S extends `${infer First}${infer Rest}`
  ? First extends Uppercase<First>
    ? `_${Lowercase<First>}${SnakeCase<Rest>}`
    : `${First}${SnakeCase<Rest>}`
  : S

type Length<T extends readonly any[]> = T['length']

type First<T extends readonly any[]> = T extends [infer F, ...any] ? F : never
type Last<T extends readonly any[]> = T extends [...any, infer L] ? L : never

type TupleToUnion<T extends readonly any[]> = T[number]

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

type IsNever<T> = [T] extends [never] ? true : false
type IsUnion<T, U = T> = IsNever<T> extends true
  ? false
  : T extends U
  ? [U] extends [T]
    ? false
    : true
  : false

type GetReturnType<F> = F extends (...args: any) => infer R ? R : never
type GetParameters<F> = F extends (...args: infer P) => any ? P : never

常见工具类型复杂度分级

难度 类型 核心技巧 实战用途
入门 Partial/Required/Readonly 映射类型 + ?/-?/readonly 每日必用
入门 Pick/Omit/Record/Extract/Exclude as 子句 + keyof + extends 每日必用
中级 ReturnType/Parameters/InstanceType infer 函数签名 类型提取
中级 DeepPartial/DeepReadonly 递归 + 条件类型 配置对象
中级 CamelCase/SnakeCase 模板字面量 + 递归 API 转换层
高级 PathOf/ValueAtPath 递归 + 模板字面量 lodash.get 类型安全
高级 UnionToIntersection 逆变体位置 infer 理论题
地狱 ParseQueryString/Format 多变量递归 类型竞技

分布式条件类型的秘密

当条件类型左边是裸类型参数(naked type parameter)且传入联合类型时,TypeScript 会自动分发:

type Wrap<T> = T extends any ? { value: T } : never
type X = Wrap<string | number>
// 等于 { value: string } | { value: number }
// 因为 string 和 number 分别代入再联合

这是 90% 的人不理解但 90% 的工具类型在用的特性。记住:想让联合"拆开来处理"就用裸泛型,想让联合"整体处理"就用元组包裹 [T] extends [U]。

模板字面量类型

TS 4.1 引入的模板字面量让字符串处理进入了类型层面:

type CSSVar<K extends string> = `--${K}`
type V = CSSVar<'primary-color'>  // '--primary-color'

type Concat<A extends string, B extends string> = `${A}${B}`

最佳实践

  1. 先写出 JS 运行时版本,再"翻译"成类型版本,能极大降低思考难度
  2. 善用 type-challenges 仓库,做 20 道中级题就能熟练大部分套路
  3. 不要在业务代码中滥用,类型体操过深会让同事看不懂;库代码再深挖
  4. 给复杂类型写测试用例,用 Expect<Equal<X, Y>> 范式防止回归
  5. 超过 5 层嵌套时拆分子类型,和正常代码一样要抽象分层

总结

类型体操不是炫技。它的本质是:把原本需要运行时才能发现的错误,提前到编译期;把原本需要手写的类型声明,交给编译器自动推导。在正确的地方(库开发、框架封装、通用工具)使用它,能极大提升代码质量和开发体验。而在业务代码中,保持克制,够用就好。

X微博Telegram

本文作者

投票

你最希望 Rosetta 优先加入哪项功能?

社区投票(演示数据,可后台删除)

评论 (5)

0 / 3000
东京留学僧
东京留学僧2026年9月2日

建议加一下关于幂等性的讨论,现在的分布式系统里这个真的太重要了,很多坑都是没处理好幂等导致的。

独立开发者阿明
独立开发者阿明aming.dev2026年9月2日

楼主,我按照你的步骤操作后启动报错:Error creating bean with name 'dataSource',版本是 Spring Boot 3.2,请问有遇到过吗?

DevOps小能手
DevOps小能手devops-lab.cn2026年9月2日

补充一点:实际使用中如果遇到 MySQL 的 8 小时超时问题,可以在连接串里加 autoReconnect=true 参数,虽然官方不推荐但挺好用的。

产品汪本汪
产品汪本汪pmdiary.io2026年9月1日

太及时了,正好项目里要上 Redis 集群,照着来一遍省了好多事,谢谢!

代码幽灵
代码幽灵ghostdev.blog2026年9月1日

作为一个刚入行的后端新人,这篇文章帮我理清了好多概念,谢谢博主持续输出高质量内容!

相关文章

测试金字塔:单元/集成/E2E 测试比例与落地

测试金字塔:单元/集成/E2E 测试比例与落地

系统解析测试金字塔架构:从底层单元测试(大量快速、Mock 隔离依赖)、中层集成测试(服务/数据库/消息协作真实交互)、顶层 E2E 测试(真实用户路径少量精测)的推荐比例 70% / 20% / 10%,附项目覆盖率指标与落地实践。

1 分钟阅读
WebAssembly 入门:Rust 编译 WASM + JS 调用

WebAssembly 入门:Rust 编译 WASM + JS 调用

从零搭建 Rust → WebAssembly 开发流程:wasm-pack 工具链、wasm-bindgen 类型绑定、JavaScript 同步/异步调用 WASM 函数、内存共享与 TypedArray 传递大数据,适合计算密集型任务移植到浏览器端。

1 分钟阅读
PostgreSQL 查询优化技巧

PostgreSQL 查询优化技巧

深入掌握 PostgreSQL 查询优化的核心方法:从 EXPLAIN ANALYZE 执行计划解读,到索引类型选择(B-tree/GIN/BRIN)、统计信息更新、连接策略调整、分区表设计,全方位提升数据库查询性能。

1 分钟阅读
Zero Trust 安全架构入门:永不信任,始终验证

Zero Trust 安全架构入门:永不信任,始终验证

零信任安全模型系统入门:以"永不信任,始终验证"为核心原则,打破传统边界防护(VPN=内部可信)的思维。从身份认证(MFA/SAML)、设备健康检查、最小权限 RBAC、微隔离 mTLS、持续信任评分到可观测审计链路的 6 大支柱详解,附落地实施路线。

1 分钟阅读
Rust 所有权与借用机制:彻底理解生命周期

Rust 所有权与借用机制:彻底理解生命周期

系统攻克 Rust 最独特概念:所有权规则、可变/不可变借用约束、引用生命周期标注。通过编译错误示例 + 修复方案,彻底掌握借用检查器思维方式,写出安全零抽象开销的系统代码。

1 分钟阅读
Linux 性能调优:perf_events + bpftrace + BCC

Linux 性能调优:perf_events + bpftrace + BCC

从 CPU、内存、IO、网络四个维度,使用 perf_events 采样堆栈、bpftrace 一行脚本追踪内核点、BCC 工具集 biolatency/offcputime,快速定位生产服务器性能瓶颈,附真实排查思路。

1 分钟阅读