<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          TypeScript 4.1 新特性:字符串模板類型,Vuex 終于有救了?

          共 3389字,需瀏覽 7分鐘

           ·

          2020-09-08 09:12

          TypeScript 4.1 快要發(fā)布了,老爺子 Anders Hejlsberg[1] 加入了一項重大更新,「字符串模板類型」 的支持。昨天看到這個更新的我特別興奮,曾幾何時,只要一遇到字符串拼接相關(guān)的類型,TypeScript 就束手無策了,比如:

          • Vuex 中加了 namespace 以后,dispatch 一個 mutation type 會帶上前綴 dispatch('cart/add')

          • lodashget 方法,可以對一個對象進(jìn)行 get(obj, 'a.b.c') 這樣的讀取。

          現(xiàn)在 4.1 加入的這個新功能讓這一切都擁有了可能。

          基礎(chǔ)語法

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

          type?EventNameextends?string>?=?`${T}Changed`;
          type?T0?=?EventName<'foo'>;??//?'fooChanged'
          type?T1?=?EventName<'foo'?|?'bar'?|?'baz'>;??//?'fooChanged'?|?'barChanged'?|?'bazChanged'
          type?Concatextends?string,?S2?extends?string>?=?`${S1}${S2}`;
          type?T2?=?Concat<'Hello',?'World'>;??//?'HelloWorld'

          字符串模板中的聯(lián)合類型會被展開后排列組合:

          type?T3?=?`${'top'?|?'bottom'}-${'left'?|?'right'}`;
          //?'top-left'?|?'top-right'?|?'bottom-left'?|?'bottom-right'

          新增關(guān)鍵字

          為了這個功能,老爺子在 TS 中新增了 uppercase, lowercase, capitalize, uncapitalize 這些關(guān)鍵字,用于對模板粒度字符串變量進(jìn)行處理。

          type?Casesextends?string>?=?`${uppercase?T}?${lowercase?T}?${capitalize?T}?${uncapitalize?T}`;
          type?T11?=?Cases<'bar'>;??//?'BAR?bar?Bar?bar'

          其實很簡單,就是提供了幾個處理方法:大寫、小寫,首字母大寫,首字母小寫。

          配合 infer

          特別強(qiáng)大的一點是,模板字符串可以通過 infer 關(guān)鍵字,實現(xiàn)類似于正則匹配提取的功能:

          type?MatchPairextends?string>?=?S?extends?`[${infer?A},${infer?B}]`???[A,?B]?:?unknown;
          type?T20?=?MatchPair<'[1,2]'>;??//?['1',?'2']
          type?T21?=?MatchPair<'[foo,bar]'>;??//?['foo',?'bar']

          通過 , 分割左右兩邊,再在左右兩邊分別用一個 infer 泛型接受推斷值 [${infer A},${infer B}],就可以輕松的重新組合 , 兩邊的字符串。

          配合 ... 拓展運(yùn)算符和 infer遞歸,甚至可以實現(xiàn) Join 功能:

          type?Joinextends?(string?|?number?|?boolean?|?bigint)[],?D?extends?string>?=
          ????T?extends?[]???''?:
          ????T?extends?[unknown]???`${T[0]}`?:
          ????T?extends?[unknown,?...infer?U]???`${T[0]}${D}${Join}`?:
          ????string;
          type?T30?=?Join<[1,?2,?3,?4],?'.'>;??//?'1.2.3.4'
          type?T31?=?Join<['foo',?'bar',?'baz'],?'-'>;??//?'foo-bar-baz'

          實戰(zhàn)運(yùn)用

          實現(xiàn) Vuex namespace 推斷:

          type?VuexOptions?=?{
          ???namespace?:?N,
          ???mutations:?M,
          }

          type?Action?=?N?extends?string???`${N}/${keyof?M?&?string}`?:?keyof?M

          type?Store?=?{
          ???dispatch(action:?Action):?void
          }

          declare?function?Vuex<M,?N>(options:?VuexOptions):?Store<M,?N>

          const?store?=?Vuex({
          ???namespace:?"cart"?as?const,
          ???mutations:?{
          ??????add()?{?},
          ??????remove()?{?}
          ???}
          }
          )

          store.dispatch("cart/add")
          store.dispatch("cart/remove")

          前往 Playground[2] 嘗試一下~

          實現(xiàn) lodash get 函數(shù):

          type?PropTypeextends?string>?=
          ????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<T,?P?extends?string>(obj:?T,?path:?P):?PropType<T,?P>;

          const?obj?=?{?a:?{?b:?{c:?42,?d:?'hello'?}}};

          const?value?=?get(obj,?"a.b.c")

          前往 Playground[3] 嘗試一下~

          總結(jié)

          TypeScript 4.1 帶來的這個新功能讓 TS 支持更多字符串相關(guān)的拼接場景,其實是特別實用的,希望各位看了以后都能有所收獲~

          參考資料

          [1]

          Anders Hejlsberg: https://github.com/ahejlsberg

          [2]

          Playground: https://www.typescriptlang.org/play?ts=4.1.0-pr-40336-8#code/C4TwDgpgBAagrhAHgeTMAlgewHYGcA8AsgDRQByAfFALxQDeAUFM9gIYC2EuYrAxhAH4AXOWJNm7OMFYYcuESQYBfBg1CQoAQV6zsRUpRrkoSYBGwATXFFzAATumwBzKAKgADACR0ySgPTeANYQIJgAZlCEUABkNvaOTkruUCLBoRGEqurQAMrAmHYQ+uRUtIzMUBbo3DK8ABYAFHy6Itq6xZQAlCIAbpjoFsqqFhC8ADashVBhcNg6WNiwCIgdFA2YaAvyS0iougQkJd1QeQVFh5SqvHLAcWdG8EgN5SwcXDz8IgBEvJPAX1BWNZrnhgGIKpJpPsRC8KoCLBYGp16FAlOC4VBCuxMD0IEiUSoKiolJ1VLYzgA6Ko1YD1Bo-P5+VgIr6k8mFKnVHi0xoMuzAPxYnEQVlAA

          [3]

          Playground: https://www.typescriptlang.org/play?ts=4.1.0-pr-40336-8#code/C4TwDgpgBACgTgezAFXBAPMgNLAhsACyggA9gIA7AEwGcobg4BLCgcwD4oBeAKCn-qMWrYmUq08hKAH4oAVwoBrCggDuFKAC4+AmPiKly1OooggEAMyjIZ1gNp7CAXS07+jg2ONQABgBIAbxYLCDgoAGkAXwA6QODQqAAlSJ9bcNEjCVNzKxtZeCRUSEw7cKccRM5NeSUVdVcBGuU1CgBuHh4qCABjABtcOGgLBW7gJgQNVghgTBwYDPE6BmY2dgAKBAAjACtq7CgwfWqYAEpjxBQ0Wdh2dp5uiYYoLe3uKACoXGqPze-u6oALAAmHBUaoAcgIEF6vQQ4KgkURdweFCeADdcL05NAuFApsANjscAAiXDRTbRbrEk5AA


          瀏覽 68
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级片在线播放电影 | 青春草在线观看国产 | 环亚无码| 成人伊人观看视频 | 狼友最新网址 |