TypeScript 4.1 新特性之字符串模板類型


據說TypeScript 4.1 快要發布了,作為前端的你還學得動嗎?老爺子 Anders Hejlsberg 將在4.1版本中加入了一項重大更新,那就是對「字符串模板類型」 的支持。不知道大家有什么感想,反正我看到這個更新是特別興奮,曾幾何時,只要一遇到字符串拼接相關的類型,TypeScript 就束手無策了,比如:

Typescript 高級語法進階

Vuex 中加了 namespace 以后,dispatch 一個 mutation type 會帶上前綴 dispatch('cart/add')。
lodash 的 get 方法,可以對一個對象進行 get(obj, 'a.b.c') 這樣的讀取。
現在 4.1 加入的這個新功能讓這一切都擁有了可能。

新增關鍵字

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

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

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

配合 infer

特別強大的一點是,模板字符串可以通過 infer 關鍵字,實現類似於正則匹配提取的功能:

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

實戰運用 實現 Vuex namespace 推斷:

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

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

type Store<M, N> = {
   dispatch(action: Action<M, N>): void
}

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

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

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

實現 lodash get 函數:

type PropType<T, Path extends string> =
    string extends Path ? unknown :
    Path extends keyof T ? T[Path] :
    Path extends `${infer K}.${infer R}` ? K extends keyof T ? PropType<T[K], R> : 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")


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM