深入理解 TypeScript 的模板字面量类型 - 从 ms 库的类型定义说起

前几天在写一个 NestJS 项目时,涉及读取 token 的过期时间配置,遇到了非常经典的时间格式处理库 ms。我使用的是它的最新测试版本 3.0.0-canary.1,顺便看了它的 TypeScript 类型定义,发现它用到了一个非常强大且优雅的 TypeScript 高级特性------模板字面量类型(Template Literal Types)。

这让我想深入聊聊 TypeScript 的模板字面量类型是什么,它能做什么,以及 ms 库是如何使用它来实现灵活且严谨的类型定义的。

什么是模板字面量类型?

TypeScript 在 4.1 版本中引入了模板字面量类型,灵感来源于 JavaScript 的模板字符串(Template Literals),但它发生在类型系统层面,用于构造新的字符串字面量类型。

简单来说,模板字面量类型就是用类似字符串模板的方式,拼接和组合字符串字面量类型,生成新的字符串字面量类型。

举个简单例子:

ts 复制代码
type EventName = "click" | "scroll";
type PrefixedEvent = `on${Capitalize<EventName>}`;

// PrefixedEvent 的类型等价于 "onClick" | "onScroll"

这允许我们用类型安全的方式构造复杂的字符串类型,避免"魔法字符串"导致的错误。


ms 库中的模板字面量类型示例

ms 是一个用于解析和格式化时间字符串的库,比如 "1s""2m""3h" 等。它的类型定义里,用模板字面量类型定义了可接受的字符串格式:传送门

typescript 复制代码
type Unit =
  | "Years" | "Year" | "Yrs" | "Yr" | "Y"
  | "Weeks" | "Week" | "W"
  | "Days" | "Day" | "D"
  | "Hours" | "Hour" | "Hrs" | "Hr" | "H"
  | "Minutes" | "Minute" | "Mins" | "Min" | "M"
  | "Seconds" | "Second" | "Secs" | "Sec" | "s"
  | "Milliseconds" | "Millisecond" | "Msecs" | "Msec" | "Ms";

type UnitAnyCase = Unit | Uppercase<Unit> | Lowercase<Unit>;

type StringValue =
  | `${number}`
  | `${number}${UnitAnyCase}`
  | `${number} ${UnitAnyCase}`;

这段定义的意思是:

  • 可以接受纯数字字符串,如 "1000"
  • 也可以接受数字后直接跟时间单位的字符串,如 "1s""3hours""5Msec"
  • 还可以接受数字和单位中间有空格的格式,如 "2 days""10 Minutes"

这极大提升了类型的准确性和友好度,避免传入不合法的时间单位字符串。


这有什么好处?

  • 类型安全:传入的字符串必须符合预定义的格式和单位集合,编译时就能捕获错误。
  • 代码提示:IDE 会自动提示所有有效的单位选项,减少输入错误。
  • 灵活强大:可以组合各种数字和单位形式,满足不同的使用习惯。

模板字面量类型的更多用法

模板字面量类型不仅可以拼接字符串,也能结合条件类型和映射类型,实现更复杂的类型逻辑。例如:

  • 动态生成带前缀或后缀的字符串类型
  • 根据枚举生成 API 路由字符串
  • 约束格式化的字符串类型(如时间、日期、货币等)

总结

TypeScript 的模板字面量类型为类型系统带来了非常强大的字符串类型操作能力,像 ms 这样的小工具库通过它让类型定义既严谨又灵活,极大提升了开发体验。

如果你还没用过模板字面量类型,不妨试试看,写一些实用的字符串类型,能让你的代码更安全,自动化程度更高。

** ms 库类型定义简化示例**

typescript 复制代码
type Unit = "s" | "m" | "h" | "d" | "y";
type StringValue = `${number}` | `${number}${Unit}` | `${number} ${Unit}`;

declare function ms(value: StringValue | number, options?: { long: boolean }): string | number;

用好它,你的时间字符串处理将更优雅!

练习

在ts的演练场练习一下

相关推荐
蜡台2 分钟前
uni-indexed-list 之扩展组件实现城市列表带索引查询过滤功能
前端·vue.js·uniapp·uni-indexed
LaughingZhu7 分钟前
Product Hunt 每日热榜 | 2026-06-16
前端·人工智能·经验分享·chatgpt·html
snow@li10 分钟前
前端:构建工具(Vite / Webpack)的 文件指纹(File Hash) 机制 / 浏览器缓存控制
前端·webpack·哈希算法
ayqy贾杰36 分钟前
SpaceX 收购 Cursor,马斯克花600亿美元买了个代码编辑器
前端·人工智能·机器学习
云飞云共享云桌面9 小时前
传统工作站 vs 云飞云共享云桌面:制造业设计云桌面选型深度对比
运维·服务器·前端·网络·3d·架构·制造
UXbot9 小时前
如何选择适合公司项目的UI设计工具?企业选型指南
前端·低代码·ui·团队开发·原型模式·设计规范·web app
llz_1129 小时前
web-第四次课后作业
前端·spring boot·web
武清伯MVP10 小时前
前端跨域方案大合集
前端·javascript
小刘|10 小时前
Spring AI Alibaba 集成和风天气 API 实战
java·服务器·前端
星星在线11 小时前
我是怎么把页面图片流量砍掉一半的
前端·javascript