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

TypeScript 高級類型體操

Choyeon
Choyeon
2026年8月25日 1 分鐘閱讀 383 閱讀
643 字 949 字元 更新於 2026年11月8日
TypeScript 高級類型體操
目錄

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 分鐘閱讀