這篇文章主要為大家展示了“TypeScript數(shù)據(jù)類型中模板字面量的示例分析”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“TypeScript數(shù)據(jù)類型中模板字面量的示例分析”這篇文章吧。
創(chuàng)新互聯(lián)是專業(yè)的新絳網(wǎng)站建設(shè)公司,新絳接單;提供成都網(wǎng)站建設(shè)、成都做網(wǎng)站,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行新絳網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!
模板字面量類型以字符串字面量類型為基礎(chǔ),可以通過聯(lián)合類型擴(kuò)展成多個(gè)字符串。
它們跟 JavaScript 的模板字符串是相同的語(yǔ)法,但是只能用在類型操作中。當(dāng)使用模板字面量類型時(shí),它會(huì)替換模板中的變量,返回一個(gè)新的字符串字面量:
type World = "world"; type Greeting = `hello ${World}`; // type Greeting = "hello world"
當(dāng)模板中的變量是一個(gè)聯(lián)合類型時(shí),每一個(gè)可能的字符串字面量都會(huì)被表示:
type EmailLocaleIDs = "welcome_email" | "email_heading"; type FooterLocaleIDs = "footer_title" | "footer_sendoff"; type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`; // type AllLocaleIDs = "welcome_email_id" | "email_heading_id" | "footer_title_id" | "footer_sendoff_id"
如果模板字面量里的多個(gè)變量都是聯(lián)合類型,結(jié)果會(huì)交叉相乘,比如下面的例子就有 2 2 3 一共 12 種結(jié)果:
type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`; type Lang = "en" | "ja" | "pt"; type LocaleMessageIDs = `${Lang}_${AllLocaleIDs}`; // type LocaleMessageIDs = "en_welcome_email_id" | "en_email_heading_id" | "en_footer_title_id" | "en_footer_sendoff_id" | "ja_welcome_email_id" | "ja_email_heading_id" | "ja_footer_title_id" | "ja_footer_sendoff_id" | "pt_welcome_email_id" | "pt_email_heading_id" | "pt_footer_title_id" | "pt_footer_sendoff_id"
如果真的是非常長(zhǎng)的字符串聯(lián)合類型,推薦提前生成,這種還是適用于短一些的情況。
模板字面量最有用的地方在于你可以基于一個(gè)類型內(nèi)部的信息,定義一個(gè)新的字符串,讓我們舉個(gè)例子:
有這樣一個(gè)函數(shù) makeWatchedObject
, 它會(huì)給傳入的對(duì)象添加了一個(gè) on
方法。在 JavaScript 中,它的調(diào)用看起來是這樣:makeWatchedObject(baseObject)
,我們假設(shè)這個(gè)傳入對(duì)象為:
const passedObject = { firstName: "Saoirse", lastName: "Ronan", age: 26, };
這個(gè) on
方法會(huì)被添加到這個(gè)傳入對(duì)象上,該方法接受兩個(gè)參數(shù),eventName
( string
類型) 和 callBack
(function
類型):
// 偽代碼 const result = makeWatchedObject(baseObject); result.on(eventName, callBack);
我們希望 eventName
是這種形式:attributeInThePassedObject + "Changed"
,舉個(gè)例子,passedObject
有一個(gè)屬性 firstName
,對(duì)應(yīng)產(chǎn)生的 eventName
為 firstNameChanged
,同理,lastName
對(duì)應(yīng)的是 lastNameChanged
,age
對(duì)應(yīng)的是 ageChanged
。
當(dāng)這個(gè) callBack
函數(shù)被調(diào)用的時(shí)候:
應(yīng)該被傳入與 attributeInThePassedObject
相同類型的值。比如 passedObject
中, firstName
的值的類型為 string
, 對(duì)應(yīng) firstNameChanged
事件的回調(diào)函數(shù),則接受傳入一個(gè) string
類型的值。age
的值的類型為 number
,對(duì)應(yīng) ageChanged
事件的回調(diào)函數(shù),則接受傳入一個(gè) number
類型的值。
返回值類型為 void
類型。
on()
方法的簽名最一開始是這樣的:on(eventName: string, callBack: (newValue: any) => void)
。 使用這樣的簽名,我們是不能實(shí)現(xiàn)上面所說的這些約束的,這個(gè)時(shí)候就可以使用模板字面量:
const person = makeWatchedObject({ firstName: "Saoirse", lastName: "Ronan", age: 26, }); // makeWatchedObject has added `on` to the anonymous Object person.on("firstNameChanged", (newValue) => { console.log(`firstName was changed to ${newValue}!`); });
注意這個(gè)例子里,on
方法添加的事件名為 "firstNameChanged"
, 而不僅僅是 "firstName"
,而回調(diào)函數(shù)傳入的值 newValue
,我們希望約束為 string
類型。我們先實(shí)現(xiàn)第一點(diǎn)。
在這個(gè)例子里,我們希望傳入的事件名的類型,是對(duì)象屬性名的聯(lián)合,只是每個(gè)聯(lián)合成員都還在最后拼接一個(gè) Changed
字符,在 JavaScript 中,我們可以做這樣一個(gè)計(jì)算:
Object.keys(passedObject).map(x => ${x}Changed)
模板字面量提供了一個(gè)相似的字符串操作:
type PropEventSource<Type> = { on(eventName: `${string & keyof Type}Changed`, callback: (newValue: any) => void): void; }; /// Create a "watched object" with an 'on' method /// so that you can watch for changes to properties. declare function makeWatchedObject<Type>(obj: Type): Type & PropEventSource<Type>;
注意,我們?cè)谶@里例子中,模板字面量里我們寫的是 string & keyof Type
,我們可不可以只寫成 keyof Type
呢?如果我們這樣寫,會(huì)報(bào)錯(cuò):
type PropEventSource<Type> = { on(eventName: `${keyof Type}Changed`, callback: (newValue: any) => void): void; }; // Type 'keyof Type' is not assignable to type 'string | number | bigint | boolean | null | undefined'. // Type 'string | number | symbol' is not assignable to type 'string | number | bigint | boolean | null | undefined'. // ...
從報(bào)錯(cuò)信息中,我們也可以看出報(bào)錯(cuò)原因,在 《TypeScript 系列之 Keyof 操作符》里,我們知道 keyof
操作符會(huì)返回 string | number | symbol
類型,但是模板字面量的變量要求的類型卻是 string | number | bigint | boolean | null | undefined
,比較一下,多了一個(gè) symbol 類型,所以其實(shí)我們也可以這樣寫:
type PropEventSource<Type> = { on(eventName: `${Exclude<keyof Type, symbol>}Changed`, callback: (newValue: any) => void): void; };
再或者這樣寫:
type PropEventSource<Type> = { on(eventName: `${Extract<keyof Type, string>}Changed`, callback: (newValue: any) => void): void; };
使用這種方式,在我們使用錯(cuò)誤的事件名時(shí),TypeScript 會(huì)給出報(bào)錯(cuò):
const person = makeWatchedObject({ firstName: "Saoirse", lastName: "Ronan", age: 26 }); person.on("firstNameChanged", () => {}); // Prevent easy human error (using the key instead of the event name) person.on("firstName", () => {}); // Argument of type '"firstName"' is not assignable to parameter of type '"firstNameChanged" | "lastNameChanged" | "ageChanged"'. // It's typo-resistant person.on("frstNameChanged", () => {}); // Argument of type '"frstNameChanged"' is not assignable to parameter of type '"firstNameChanged" | "lastNameChanged" | "ageChanged"'.
現(xiàn)在我們來實(shí)現(xiàn)第二點(diǎn),回調(diào)函數(shù)傳入的值的類型與對(duì)應(yīng)的屬性值的類型相同。我們現(xiàn)在只是簡(jiǎn)單的對(duì) callBack
的參數(shù)使用 any
類型。實(shí)現(xiàn)這個(gè)約束的關(guān)鍵在于借助泛型函數(shù):
捕獲泛型函數(shù)第一個(gè)參數(shù)的字面量,生成一個(gè)字面量類型
該字面量類型可以被對(duì)象屬性構(gòu)成的聯(lián)合約束
對(duì)象屬性的類型可以通過索引訪問獲取
應(yīng)用此類型,確?;卣{(diào)函數(shù)的參數(shù)類型與對(duì)象屬性的類型是同一個(gè)類型
type PropEventSource<Type> = { on<Key extends string & keyof Type> (eventName: `${Key}Changed`, callback: (newValue: Type[Key]) => void ): void; }; declare function makeWatchedObject<Type>(obj: Type): Type & PropEventSource<Type>; const person = makeWatchedObject({ firstName: "Saoirse", lastName: "Ronan", age: 26 }); person.on("firstNameChanged", newName => { // (parameter) newName: string console.log(`new name is ${newName.toUpperCase()}`); }); person.on("ageChanged", newAge => { // (parameter) newAge: number if (newAge < 0) { console.warn("warning! negative age"); } })
這里我們把 on
改成了一個(gè)泛型函數(shù)。
當(dāng)一個(gè)用戶調(diào)用的時(shí)候傳入 "firstNameChanged"
,TypeScript 會(huì)嘗試著推斷 Key
正確的類型。它會(huì)匹配 key
和 "Changed"
前的字符串 ,然后推斷出字符串 "firstName"
,然后再獲取原始對(duì)象的 firstName
屬性的類型,在這個(gè)例子中,就是 string
類型。
TypeScript 的一些類型可以用于字符操作,這些類型處于性能的考慮被內(nèi)置在編譯器中,你不能在 .d.ts
文件里找到它們。
把每個(gè)字符轉(zhuǎn)為大寫形式:
type Greeting = "Hello, world" type ShoutyGreeting = Uppercase<Greeting> // type ShoutyGreeting = "HELLO, WORLD" type ASCIICacheKey<Str extends string> = `ID-${Uppercase<Str>}` type MainID = ASCIICacheKey<"my_app"> // type MainID = "ID-MY_APP"
把每個(gè)字符轉(zhuǎn)為小寫形式:
type Greeting = "Hello, world" type QuietGreeting = Lowercase<Greeting> // type QuietGreeting = "hello, world" type ASCIICacheKey<Str extends string> = `id-${Lowercase<Str>}` type MainID = ASCIICacheKey<"MY_APP"> // type MainID = "id-my_app"
把字符串的第一個(gè)字符轉(zhuǎn)為大寫形式:
type LowercaseGreeting = "hello, world"; type Greeting = Capitalize<LowercaseGreeting>; // type Greeting = "Hello, world"
把字符串的第一個(gè)字符轉(zhuǎn)換為小寫形式:
type UppercaseGreeting = "HELLO WORLD"; type UncomfortableGreeting = Uncapitalize<UppercaseGreeting>; // type UncomfortableGreeting = "hELLO WORLD"
從 TypeScript 4.1 起,這些內(nèi)置函數(shù)會(huì)直接使用 JavaScript 字符串運(yùn)行時(shí)函數(shù),而不是本地化識(shí)別 (locale aware)。
function applyStringMapping(symbol: Symbol, str: string) { switch (intrinsicTypeKinds.get(symbol.escapedName as string)) { case IntrinsicTypeKind.Uppercase: return str.toUpperCase(); case IntrinsicTypeKind.Lowercase: return str.toLowerCase(); case IntrinsicTypeKind.Capitalize: return str.charAt(0).toUpperCase() + str.slice(1); case IntrinsicTypeKind.Uncapitalize: return str.charAt(0).toLowerCase() + str.slice(1); } return str; }
以上是“TypeScript數(shù)據(jù)類型中模板字面量的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
新聞標(biāo)題:TypeScript數(shù)據(jù)類型中模板字面量的示例分析
當(dāng)前路徑:http://bm7419.com/article38/gosepp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、自適應(yīng)網(wǎng)站、品牌網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、網(wǎng)站策劃、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)