Notice: 函数 WP_Object_Cache::get 的调用方法不正确。 缓存键不能为空字符串。 请查阅调试 WordPress来获取更多信息。 (这个消息是在 6.1.0 版本添加的。) in /www/wwwroot/zblog_xzdbk_com/wp-includes/functions.php on line 6170

Notice: 函数 WP_Object_Cache::set 的调用方法不正确。 缓存键不能为空字符串。 请查阅调试 WordPress来获取更多信息。 (这个消息是在 6.1.0 版本添加的。) in /www/wwwroot/zblog_xzdbk_com/wp-includes/functions.php on line 6170

TypeScript高级类型体操:从infer到模板字面量类型

TypeScript 的类型系统到底能多强?从 infer 到模板字面量类型,带你玩转高级类型体操

TypeScript 的类型系统是图灵完备的——这意味着你完全可以在类型层面编写程序,就像在值层面一样自由。但很多开发者只用了最简单的类型标注,白白浪费了这颗强大引擎的潜力。今天,我们就从 infer 关键字出发,一路深入到模板字面量类型,最后用一个“类型版 JSON 解析器”来检验你的学习成果。

条件类型与 infer:类型推断的核心工具

条件类型是 TypeScript 类型体操的基石。它就像类型世界的 if/else:

type IsString<T> = T extends string ? true : false;

但单纯的条件类型还不够灵活,搭配 infer 关键字后,你可以从复杂类型中提取出子类型。例如,从函数类型中提取返回值类型:

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

通过 条件类型infer 的组合,你可以模拟出类型层面的模式匹配,从而写出高度抽象的通用类型工具。如果你还不熟悉 TypeScript 的这些高级特性,那么接下来的内容可能会彻底改变你对类型系统的认知。

模板字面量类型:在字符串层面进行模式匹配

模板字面量类型是 TypeScript 4.1 引入的杀手级特性。它让你可以在类型层面操作字符串字面量,就像在运行时操作字符串一样自然。

基础匹配:提取路径参数

假设你有一个路由字符串 'user/:id/profile',你想提取其中的 :id 参数名。利用 模板字面量类型infer,可以轻松做到:

type ExtractParam<T> = T extends `${string}/:${infer P}/${string}` ? P : never;

这个模式看似简单,却能够支撑起整个路由类型的推导。

大小写转换与格式化

另一个常见的场景是转换字符串的命名风格。例如,将 'camelCase' 转为 'snake_case'。借助 模板字面量类型 的递归能力,你可以实现一个类型版的 toSnakeCase

type ToSnake<T extends string> = 
  T extends `${infer C}${infer Rest}` 
    ? C extends Uppercase<C> 
      ? `_${Lowercase<C>}${ToSnake<Rest>}` 
      : `${C}${ToSnake<Rest>}`
    : T;

解析复杂字符串模式

当你需要从 'type:user|id:123' 这样的字符串中提取键值对时,模板字面量类型 同样可以胜任——只需多次嵌套条件类型与 infer,就能在类型层面完成字符串解析。

映射类型与键重新映射:从现有类型到新类型

映射类型(Mapped Types)允许你对对象类型的每个属性进行转换。而 TypeScript 4.1 引入的 as 子句,更是实现了键的重新映射(Key Remapping)。结合前面的条件类型,你可以写出极为精确的类型变换。

例如,将所有以 get 开头的属性名改为 set 开头:

type GettersToSetters<T> = {
  [K in keyof T as K extends `get${infer P}` ? `set${P}` : K]: T[K]
};

这是 高级类型 中非常实用的技巧,而背后的整套理念都属于 类型体操 的范畴——用类型编程解决实际问题,而不是仅仅为了炫技。

实战:用类型系统解析 JSON

现在我们将所有技巧结合,实现一个类型版的 JSON 解析器。它能够根据输入的 JSON 字符串字面量,静态推导出对应的 TypeScript 类型。

这个解析器会递归使用条件类型、infer、模板字面量类型和映射类型,一层层拆解字符串。比如,输入 '{"name":"Alice","age":30}',输出类型应为 { name: string; age: number }

编写这样的类型解析器需要深厚的类型功底,如果你在理解复杂类型时遇到瓶颈,不妨借助 GPT 来辅助分析——它能帮你快速解释那些嵌套的类型定义。而 TypeScript 的 高级版 功能如模板字面量类型和条件类型,正是实现这种“类型计算”的基础设施。

常见问题

❓ TypeScript 类型体操适合哪些开发场景?
在需要高度抽象类型约束时,比如框架路由的类型推导、表单校验的类型安全、API 响应类型的自动映射等。日常业务代码不建议过度使用,保持可读性更重要。
❓ 模板字面量类型能处理动态拼接的字符串吗?
不能处理运行时动态的字符串,它只对编译期已知的字符串字面量有效。但它可以配合 as const 断言来捕获常量字符串的精确类型。
❓ infer 关键字只能在条件类型中使用吗?
是的,infer 必须出现在条件类型的 extends 子句中,用来声明一个待推断的类型变量。它不能单独使用,也不能在泛型约束里使用。

相关阅读:TypeScript高级类型TypeScript类型体操infer关键字

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    请登录后查看评论内容