日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
用了模板字面量類型,同事直呼太強(qiáng)了!

假設(shè)我們想要定義一種類型來描述 CSS padding 規(guī)則,如果你了解 TypeScript 類型別名和聯(lián)合類型的話,能很容易定義出 CssPadding 類型。

創(chuàng)新互聯(lián)是一家專注于網(wǎng)站設(shè)計制作、成都網(wǎng)站設(shè)計與策劃設(shè)計,北戴河網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:北戴河等地區(qū)。北戴河做網(wǎng)站價格咨詢:18982081108

type CssPadding =
| "padding-left"
| "padding-right"
| "padding-top"
| "padding-bottom";

但如果我們想要繼續(xù)定義一種新的類型來描述 CSS margin 規(guī)則,你是不是立馬想到與定義 CssPadding 類型一樣的方式。

type MarginPadding =
| "margin-left"
| "margin-right"
| "margin-top"
| "margin-bottom";

對于以上定義的兩種類型來說,雖然它們都能滿足我們的需求。但在定義這兩種類型的過程中,仍然存在一些重復(fù)的代碼。

那么如何解決這個問題呢?這時我們可以使用 TypeScript 4.1 版本引入了新的模板字面量類型,具體的使用方式如下:

type Direction = "left" | "right" | "top" | "bottom";

type CssPadding = `padding-${Direction}`;
type MarginPadding = `margin-${Direction}`;

看完以上代碼,是不是覺得簡潔很多。與 JavaScript 中的模板字符串類似,模板字面量類型被括在反引號中,同時可以包含 ${T}? 形式的占位符,其中類型變量 T 的類型可以是 string、number、boolean? 或 bigint 類型。

模板字面量類型不僅為我們提供了連接字符串字面量的能力,而且還可以把非字符串基本類型的字面量轉(zhuǎn)換為對應(yīng)的字符串字面量類型。下面我們來舉一些具體的例子:

type EventName = `${T}Changed`;
type Concat = `${S1}-${S2}`;
type ToString = `${T}`;

type T0 = EventName<"foo">; // 'fooChanged'
type T1 = Concat<"Hello", "World">; // 'Hello-World'
type T2 = ToString<"阿寶哥" | 666 | true | -1234n>; // "阿寶哥" | "true" | "666" | "-1234"

對于上述的例子來說,其實并不復(fù)雜。但現(xiàn)在問題來了,如果傳入 EventName 或 Concat 工具類型的實際類型是聯(lián)合類型的話,那么結(jié)果又會是怎樣呢?接下來,我們來驗證一下:

type T3 = EventName<"foo" | "bar" | "baz">; 
// "fooChanged" | "barChanged" | "bazChanged"
type T4 = Concat<"top" | "bottom", "left" | "right">;
// "top-left" | "top-right" | "bottom-left" | "bottom-right"

為什么會生成這樣的類型呢?這是因為對于模板字面量類型來說,當(dāng)類型占位符的實際類型是聯(lián)合類型(A |B |C)的話,就會被自動展開:

`[${A|B|C}]` => `[${A}]` | `[${B}]` | `[${C}]`

而對于包含多個類型占位符的情形,比如 Concat 工具類型。多個占位符中的聯(lián)合類型解析為叉積:

`${A|B}-${C|D}` => `${A}-${C}` | `${A}-${D}` | `${B}-${C}` | `${B}-${D}`

了解完上述的運(yùn)算規(guī)則,你應(yīng)該就能理解生成的 T3 和 T4 類型了。

在使用模板字面量類型的過程中,我們還可以使用 TypeScript 提供的,用于處理字符串類型的內(nèi)置工具類型,比如 Uppercase、Lowercase、Capitalize 和 Uncapitalize。具體的使用方式是這樣的:

type GetterName = `get${Capitalize}`;
type Cases = `${Uppercase} ${Lowercase} ${Capitalize} ${Uncapitalize}`;

type T5 = GetterName<'foo'>; // "getFoo"
type T6 = Cases<'bar'>; // "BAR bar Bar bar"

其實,模板字面量類型的能力是很強(qiáng)大的,結(jié)合 TypeScript 的條件類型和 infer 關(guān)鍵字我們還可以實現(xiàn)類型推斷。

type Direction = "left" | "right" | "top" | "bottom";
type InferRoot = T extends `${infer R}${Capitalize}` ? R : T;

type T7 = InferRoot<"marginRight">; // "margin"
type T8 = InferRoot<"paddingLeft">; // "padding"

在以上代碼中,InferRoot 工具類型除了利用模板字面量類型之外,還使用了 TypeScript 條件類型和 infer。如果你對這兩個知識點,還不了解的話,可以觀看 “用了 TS 條件類型,同事直呼 YYDS?” 和 “學(xué)會 TS infer,寫起泛型真香!” 這兩篇文章。

此外,TypeScript 4.1 版本允許我們使用 as 子句對映射類型中的鍵進(jìn)行重新映射。它的語法如下:

type MappedTypeWithNewKeys = {
[K in keyof T as NewKeyType]: T[K]
// ^^^^^^^^^^^^^
// This is the new syntax!
}

其中 NewKeyType 的類型必須是 string | number | symbol 聯(lián)合類型的子類型。在重新映射的過程中,結(jié)合模板字面量類型所提供的能力,我們就可以實現(xiàn)一些有用的工具類型。

比如,我們可以定義一個 Getters 工具類型,用于為對象類型生成對應(yīng)的 Getter 類型:

type Getters = {
[K in keyof T as `get${Capitalize}`]: () => T[K]
};

interface Person {
name: string;
age: number;
location: string;
}

type LazyPerson = Getters;
// {
// getName: () => string;
// getAge: () => number;
// getLocation: () => string;
// }

在以上代碼中,因為 keyof  T 返回的類型可能會包含 symbol 類型,而 Capitalize 工具類型要求處理的類型需要是 string 類型的子類型,所以需要通過交叉運(yùn)算符進(jìn)行類型過濾。

除了實現(xiàn)簡單的工具類型之外,我們還可以實現(xiàn)比較復(fù)雜的工具類型。比如,用于獲取對象類型中,任意層級屬性的類型。

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 getPropValue(
obj: T,
path: P
): PropType;

const obj = { a: { b: { c: 666, d: "阿寶哥" } } };
let a = getPropValue(obj, "a"); // { b: {c: number, d: string } }
let ab = getPropValue(obj, "a.b"); // {c: number, d: string }
let abd = getPropValue(obj, "a.b.d"); // string

在以上代碼中,PropType 工具類型涉及 TypeScript 中的多個核心知識點。


標(biāo)題名稱:用了模板字面量類型,同事直呼太強(qiáng)了!
標(biāo)題鏈接:http://www.dlmjj.cn/article/cdjejhg.html