原来typescript也可以这么有趣

原来typescript也可以这么有趣,看好了,下面来看一段有趣的代码。

ts 复制代码
type Space = ' ' | '\n' | '\t';
type TrimLeft<S extends string> = S extends `${Space}${infer R}`
  ? TrimLeft<R>
  : S;

再看使用方式如下:

ts 复制代码
type TrimLeftStr = TrimLeft<'  Hello World  '>; // expected to be 'Hello World  '

查看结果如下图所示:

从来没有想过ts也可以去除字符串的空白,这简直令人难以想象。言归正传,我们先来解释一下以上代码的含义。

首先定一个了一个Space类型,这个类型是一个联合类型,第一个就是一段空白字符串,请记住中间是有空白的,第二个\n为换行符,表示回车换行,也就是将当前位置移到下一行的开头,第三个\t为水平制表符,也就是将当前位置移到下一个tab位置,总的说来,就是一个空白符的联合类型。

接着我们定义了一个去除左边空白的泛型,泛型S使用extends确定类型限定在字符串类型,因为只有字符串才需要清除空白,紧接着类型值我们使用一个三元表达式,判断条件就是泛型S是否继承一个模板字符串,恰恰有趣的就是这个模板字符串,这个模板字符串由我们定义的空白类型以及使用infer推断剩余字符串而组成的模板字符串。

note: infer是typescript的一个关键字,用于条件类型当中推断参数。

如果字符串满足模板字符串所定义的类型,那么就递归调用去除字符串类型,这时候参数变成了我们推断的R类型,否则就直接返回这个泛型S,这样也就达到了我们去除左边字符串空白的效果。

那么按照同样的思路,我们清除字符串右边空白也就可以轻而易举的实现,如下所示:

ts 复制代码
type Space = ' ' | '\n' | '\t';
type TrimRight<S extends string> = S extends `${infer R}${Space}`
  ? TrimRight<R>
  : S;

可以看到,我们只做了两个地方的改动,第一个当然就是类型名的更换,而另一个就是模板字符串中空白类型更换了一下位置。

如此一来,我们的trim类型,消除两边空白不就可以实现了吗,如下所示:

ts 复制代码
type Space = ' ' | '\n' | '\t';
type Trim<S extends string> = S extends `${Space}${infer R}${Space}`
  ? Trim<R>
  : S;

完美,typescript真的很有趣,这更像是js操作字符串了,不过话又说回来,这种操作恐怕只能自己玩玩,真要用到业务当中,嗯,我想应该不会有人写带空白字符串的类型吧。

以上代码段参考自type-challenges,并总结到我的代码段合集中。

相关推荐
Flynt4 小时前
Agent跑完就失忆?Cloudflare这个开源项目给它装了块硬盘
typescript·开源
Goodbye4 小时前
React + TypeScript 企业级开发实战:从类型约束到组件架构演进
typescript
烬羽4 小时前
组件拆了,逻辑没拆——自定义 Hook 才是 React 业务逻辑的正当归属
react.js·架构·typescript
今日无bug4 小时前
Bun 入门:零配置 JS/TS 运行时 + 包管理器
typescript·bun
苏灿烤鱼6 小时前
GitHub #1 拆解|它说自己在进化,但 worker 跑的是你本机权限,不是沙箱
人工智能·typescript·agent
To_OC1 天前
从一个名字编辑组件开始,我把 React + TS 的数据流和副作用彻底搞明白了
前端·react.js·typescript
A24207349301 天前
Vue + TypeScript 请求数据后结合 Element UI 实现树形菜单与下拉选择
vue.js·ui·typescript
星栈1 天前
我以为 TS7.0 只是换个版本号,结果编译快了 9 倍,也踩了 5 个坑
后端·typescript·node.js
GISHUB1 天前
Express + TypeScript + ESM 后端框架示例(@yao-pkg/pkg 打包)
typescript·express
苏灿烤鱼1 天前
今日 GitHub 热门|Agent 记忆重回榜首,+2,690 项目却只排第三
typescript·agent·资讯