调用函数实现字符串复制的功能_TypeScript 4.1 新特性:字符串模板类型

a6fd902bcc304e406396264310979f11.png

TypeScript 4.1 快要发布了,老爷子 Anders Hejlsberg 加入了一项重大更新,「字符串模板类型」 的支持。昨天看到这个更新的我特别兴奋,曾几何时,只要一遇到字符串拼接相关的类型,TypeScript 就束手无策了,比如:

  • Vuex 中加了 namespace 以后,dispatch 一个 mutation type 会带上前缀 dispatch('cart/add')。
  • lodash 的 get 方法,可以对一个对象进行 get(obj, 'a.b.c') 这样的读取。

现在 4.1 加入的这个新功能让这一切都拥有了可能。

基础语法

它的语法和 es 里的字符串模板很相似,所以上手成本也很低,先看几个例子:

type EventName = `${T}Changed`;type T0 = EventName;  // 'fooChanged'type T1 = EventName;  // 'fooChanged' | 'barChanged' | 'bazChanged'复制代码
type Concat = `${S1}${S2}`;type T2 = Concat;  // 'HelloWorld'复制代码

字符串模板中的联合类型会被展开后排列组合:

type T3 = `${'top' | 'bottom'}-${'left' | 'right'}`;  // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'复制代码

新增关键字

为了这个功能,老爷子在 TS 中新增了 uppercase, lowercase, capitalize, uncapitalize 这些关键字,用于对模板粒度字符串变量进行处理。

type Cases = `${uppercase T} ${lowercase T} ${capitalize T} ${uncapitalize T}`;type T11 = Cases;  // 'BAR bar Bar bar'复制代码

其实很简单,就是提供了几个处理方法:大写、小写,首字母大写,首字母小写。

配合 infer

特别强大的一点是,模板字符串可以通过 infer 关键字,实现类似于正则匹配提取的功能:

type MatchPair = S extends `[${infer A},${infer B}]` ? [A, B] : unknown;type T20 = MatchPair;  // ['1', '2']type T21 = MatchPair;  // ['foo', 'bar']复制代码

通过 , 分割左右两边,再在左右两边分别用一个 infer 泛型接受推断值 [${infer A},${infer B}],就可以轻松的重新组合 , 两边的字符串。

配合 ... 拓展运算符和 infer递归,甚至可以实现 Join 功能:

type Join =    T extends [] ? '' :    T extends [unknown] ? `${T[0]}` :    T extends [unknown, ...infer U] ? `${T[0]}${D}${Join}` :    string;type T30 = Join;  // '1.2.3.4'type T31 = Join;  // 'foo-bar-baz'复制代码

实战运用

实现 Vuex namespace 推断:

type VuexOptions = {   namespace?: N,   mutations: M,}type Action = N extends string ? `${N}/${keyof M & string}` : keyof Mtype Store = {   dispatch(action: Action): void}declare function Vuex(options: VuexOptions): Storeconst store = Vuex({   namespace: "cart" as const,   mutations: {      add() { },      remove() { }   }})store.dispatch("cart/add")store.dispatch("cart/remove")复制代码

前往 Playground 尝试一下~

实现 lodash get 函数:

type PropType =    string extends Path ? unknown :    Path extends keyof T ? T[Path] :    Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType : unknown :    unknown;declare function get(obj: T, path: P): PropType;const obj = { a: { b: {c: 42, d: 'hello' }}};const value = get(obj, "a.b.c")复制代码

前往 Playground 尝试一下~

总结

TypeScript 4.1 带来的这个新功能让 TS 支持更多字符串相关的拼接场景,其实是特别实用的,希望各位看了以后都能有所收获~

最后

刚整理 2020 年全套最新精品技术资料免费发给你! (原价最少6999,超200G!)

初级-中级-高级前端工程师从入门到大神

8b68514dfe8300a2d4d34800f4e46c4c.png
011b9885f1064dd7e1f8d3f2793401af.png

前端工程师必读100本系列

47eeb9ca0d848122ead875cdab0145ee.png
2efad467dc84bad62fcb473131499aa4.png

领取干货:

1. 点赞+评论

2. 点头像关注后,私信小编,回复:1024

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值