真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

TypeScript4.1中的模板字面類型是什么

這篇文章主要介紹“TypeScript 4.1中的模板字面類型是什么”,在日常操作中,相信很多人在TypeScript 4.1中的模板字面類型是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”TypeScript 4.1中的模板字面類型是什么”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的周至網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

新的語言特性

模板字面類型

自 ES6 開始,我們就可以通過模板字面量(Template Literals)的特性,用反引號來書寫字符串,而不只是單引號或雙引號:

const message = `text`;

正如 Flavio Copes 所言,模板字面量提供了之前用引號寫的字符串所不具備的特性:

  • 定義多行字符串非常方便

  • 可以輕松地進(jìn)行變量和表達(dá)式的插值

  • 可以用模板標(biāo)簽創(chuàng)建 DSL(Domain Specific Language,領(lǐng)域特定語言)

模板字面量類型和 JavaScript 中的模板字符串語法完全一致,只不過是用在類型定義里面:

type Entity = 'Invoice';  type Notification = `${Entity} saved`; // 等同于 // type Notification = 'Invoice saved';   type Viewport = 'md' | 'xs'; type Device = 'mobile' | 'desktop';  type Screen = `${Viewport | Device} screen`; // 等同于下面這一行 // type Screen = 'md screen' | 'xs screen' | 'mobile screen' | 'desktop screen';

當(dāng)我們定義了一個具體的字面量類型時,TypeScript 會通過拼接內(nèi)容的方式產(chǎn)生新的字符串字面量類型。

鍵值對類型中鍵的重新映射(Key Remapping)

映射類型可以基于任意鍵創(chuàng)建新的對象類型。 字符串字面量可以用作映射類型中的屬性名稱:

type Actions = { [K in 'showEdit' | 'showCopy' | 'showDelete']?: boolean; }; // 等同于 type Actions = {   showEdit?:   boolean,   showCopy?:   boolean,   showDelete?: boolean };

如果你想創(chuàng)建新鍵或過濾掉鍵,TypeScript 4.1 允許你使用新的 as 子句重新映射映射類型中的鍵:

type MappedTypeWithNewKeys = {     [K in keyof T as NewKeyType]: T[K] }

TypeScript Remapping KeysThe new as clause lets you leverage features like  template literal types to easily create new property names based on old ones.  Keys can be filtered by producing never so that you don’t have to use an extra  Omit helper type in some cases: 通過使用新的 as  子句,我們可以利用模板字面量類型之類的特性輕松地基于舊屬性創(chuàng)建新屬性名稱。我們可以通過輸出 never 來過濾鍵,這樣在某些情況下就不必使用額外的 Omit  輔助類型:

type Getters = {     [K in keyof T as `get${Capitalize}`]: () => T[K] };  interface Person {     name: string;     age: number;     location: string; }  type LazyPerson = Getters; //   ^ = type LazyPerson = { //       getName: () => string; //       getAge: () => number; //       getLocation: () => string; //   }  // 去掉 'kind' 屬性 type RemoveKindField = {     [K in keyof T as Exclude]: T[K] };  interface Circle {     kind: "circle";     radius: number; }  type KindlessCircle = RemoveKindField; //   ^ = type KindlessCircle = { //       radius: number; //   }

TypeScript 利用帶有 as 子句的模板文字類型 (source)

JSX 工廠函數(shù)

JSX 代表 JavaScript XML,它允許我們使用 JavaScript 編寫 HTML 元素并將其放置在 DOM 中,而無需任何  createElement() 或 appendChild() 方法,例如:

const greeting = 
Yes I can do it!
; ReactDOM.render(greeting, document.getElementById('root'));

TypeScript 4.1 通過編譯器選項 jsx 的兩個新選項支持 React 17 的 jsx 和 jsxs 工廠函數(shù):

  • react-jsx

  • react-jsxdev

“這些選項分別用于生產(chǎn)和開發(fā)編譯。通常,一個選項可以擴(kuò)展自另一個選項?!?— TypeScript發(fā)版說明

以下是兩個用于生產(chǎn)和開發(fā)的 TypeScript 配置文檔的兩個示例:

// ./src/tsconfig.json {   "compilerOptions": {     "module": "esnext",     "target": "es2015",     "jsx": "react-jsx",     "strict": true   },   "include": ["./**/*"] }

開發(fā)配置:

// ./src/tsconfig.dev.json {   "extends": "./tsconfig.json",   "compilerOptions": {     "jsx": "react-jsxdev"   } }

如下圖所示,TypeScript 4.1 支持在像 React 這樣的 JSX 環(huán)境中進(jìn)行類型檢查:

TypeScript 4.1中的模板字面類型是什么  

遞歸條件類型

另一個新增功能是遞歸條件類型,它允許它們在分支中引用自己,從而能夠更靈活地處理條件類型,使得編寫遞歸類型別名更加容易。下面是一個使用 Awaited  展開深層嵌套的 Promise 的示例:

type Awaited = T extends PromiseLike ? Awaited : T;  // 類似 `promise.then(...)`, 但是在類型上更加精確 declare function customThen(     p: Promise,     onFulfilled: (value: Awaited) => U ): Promise>;

但是應(yīng)當(dāng)注意的是,TypeScript 需要更多時間來進(jìn)行遞歸類型的類型檢查。Microsoft 警告,應(yīng)以負(fù)責(zé)任的態(tài)度謹(jǐn)慎使用它們。

Checked indexed accesses 索引訪問檢查

_ TypeScript 中的索引簽名允許可以像下面的 Options 接口中那樣訪問任意命名的屬性:

interface Options {   path: string;   permissions: number;    // Extra properties are caught by this index signature.   // 額外的屬性將被這個   [propName: string]: string | number; }  function checkOptions(opts: Options) {   opts.path; // string   opts.permissions; // number    // 這些都可以!因為類型都是 string | number   opts.yadda.toString();   opts["foo bar baz"].toString();   opts[Math.random()].toString(); }

在這里,我們看到不是 path 以及 permissions 的屬性應(yīng)具有 string | number 類型:

TypeScript 4.1 提供了一個新的標(biāo)志 --noUncheckedIndexedAccess,使得每次屬性訪問(如  opts.path)或索引訪問(如 opts [“ blabla”] )都可能未定義。這意味著如果我們需要訪問上一個示例中的 opts.path  之類的屬性,則必須檢查其是否存在或使用非 null 斷言運算符(后綴 ! 字符):

function checkOptions(opts: Options) {   opts.path; // string   opts.permissions; // number    // 以下代碼在 noUncheckedIndexedAccess 開啟時是非法的   opts.yadda.toString();   opts["foo bar baz"].toString();   opts[Math.random()].toString();    // 檢查屬性是否真的存在   if (opts.yadda) {     console.log(opts.yadda.toString());   }    // 直接使用非空斷言操作符   opts.yadda!.toString(); }

--noUncheckedIndexedAccess 標(biāo)志對于捕獲很多錯誤很有用,但是對于很多代碼來說可能很嘈雜。 這就是為什么 --strict  開關(guān)不會自動啟用它的原因。

不需要 baseUrl 指定路徑

在 TypeScript 4.1 之前,要能夠使用 tsconfig.json 文件中的 paths,必須聲明 baseUrl 參數(shù)。  在新版本中,可以在不帶 paths 選項的情況下指定 baseUrl。 這解決了自動導(dǎo)入中路徑不暢的問題。

{     "compilerOptions": {         "baseUrl": "./src",         "paths": {             "@shared": ["@shared/"] // This mapping is relative to "baseUrl"         }     } }

checkJs 默認(rèn)打開 allowJs

如果您有一個 JavaScript 項目,正在其中使用 checkJs 選項檢查 .js 文件中的錯誤,則還應(yīng)該聲明 allowJs 以允許編譯  JavaScript 文件。而 TypeScript 4.1 中,默認(rèn)情況下 checkJs 意味著 allowJs:

{   compilerOptions: {     allowJs: true,     checkJs: true   } }

JSDoc @see 標(biāo)簽的編輯器支持

在編輯器中使用 TypeScript 時,現(xiàn)在對 JSDoc 標(biāo)簽 @see 有了更好的支持,這將改善TypeScript 4.1的可用性:

// @filename: first.ts export class C {}  // @filename: main.ts import * as first from "./first";  /**  * @see first.C  */ function related() {}

不兼容改變

lib.d.ts 變動

結(jié)構(gòu)和 DOM 的環(huán)境聲明,使您可以輕松地開始編寫經(jīng)過類型檢查的 JavaScript 代碼。

該文件自動包含在 TypeScript 項目的編譯上下文中。 您可以通過指定 --noLib 編譯器命令行標(biāo)志或在 tsconfig.json 中配置  noLib 為 true 來排除它。

在 TypeScript 4.1 中,由于 DOM 類型是自動生成的,lib.d.ts 可能具有一組變動的 API,例如,從 ES2016 中刪除的  Reflect.enumerate。

abstract 成員不能被標(biāo)記為 async

在另一個重大更改中,標(biāo)記為 abstract 的成員不能被再標(biāo)記為 async。 因此,要修復(fù)您的代碼,必須刪除 async 關(guān)鍵字:

abstract class MyClass {   // 在 TypeScript 4.1 中必須刪除 async   abstract async create(): Promise; }

any/unknown 向外傳播

在 TypeScript 4.1 之前,對于像 foo && somethingElse 這樣的表達(dá)式, foo 的類型是 any 或  unknown。 整個表達(dá)式的類型將是 somethingElse 的類型,在以下示例中就是 {someProp:string} :

declare let foo: unknown; declare let somethingElse: { someProp: string }; let x = foo && somethingElse;

在 TypeScript 4.1 中, any 和 unknown 都將向外傳播,而不是在右側(cè)傳播。通常,這個變更合適的解決方法是從 foo  && someExpression 切換到 !!foo && someExpression。

  • 注意:雙重感嘆號(!!)是將變量強(qiáng)制轉(zhuǎn)換為布爾值(真或假)的一種簡便方法。

Promise 中 resolve 的參數(shù)不再是可選類型

Promise 中 resolve 的參數(shù)不再是可選的,例如下面的代碼:

new Promise((resolve) => {   doSomethingAsync(() => {     doSomething();     resolve();   }); });

這段代碼在 TypeScript 4.1 中編譯會報錯:

resolve()   ~~~~~~~~~ error TS2554: Expected 1 arguments, but got 0.   An argument for 'value' was not provided.

要解決這個問題,必須在 Promise 中給 resolve 提供至少一個值,否則,在確實需要不帶參數(shù)的情況下調(diào)用 resolve()  的情況下,必須使用顯式的 void 泛型類型參數(shù)聲明 Promise:

new Promise((resolve) => {   doSomethingAsync(() => {     doSomething();     resolve();   }); });

條件展開將會創(chuàng)建可選屬性

在 JavaScript 中,展開運算符 { ...files } 不會作用于假值,例如 files 為 null 或者 undefined。

在以下使用條件傳播的示例中,如果定義了 file,則將傳播 file.owner 的屬性。否則,不會將任何屬性傳播到返回的對象中:

function getOwner(file?: File) {   return {     ...file?.owner,     defaultUserId: 123,   }; }

在TypeScript 4.1之前, getOwner 返回基于每個展開對象的聯(lián)合類型:

{ x: number } | { x: number, name: string, age: number, location: string }
  • 如果定義了 file,則會擁有來自Person(所有者的類型)的所有屬性。

  • 否則,結(jié)果中一個都不會展示

但是事實證明,這樣的代價最終會變得非常高昂,而且通常無濟(jì)于事。在單個對象中存在數(shù)百個展開對象,每個展開對象都可能增加數(shù)百或數(shù)千個屬性。  為了更好的性能,在TypeScript 4.1中,返回的類型有時使用全部可選屬性:

{     x:         number;     name?:     string;     age?:      number;     location?: string; }

不匹配的參數(shù)將不再關(guān)聯(lián)

過去,彼此不對應(yīng)的參數(shù)在 TypeScript 中通過將它們與 any 類型關(guān)聯(lián)而彼此關(guān)聯(lián)。

在下面的重載示例(為同一功能提供多種功能類型)中, pickCard 函數(shù)將根據(jù)用戶傳入的內(nèi)容返回兩個不同的內(nèi)容。如果用戶傳入表示 deck  的對象,則該函數(shù)將選擇 card。 如果用戶選擇了 card,他們將得到他們選擇的 card:

let suits = ["hearts", "spades", "clubs", "diamonds"];  function pickCard(x: { suit: string; card: number }[]): number; function pickCard(x: number): { suit: string; card: number }; function pickCard(x: any): any {   // Check to see if we're working with an object/array   // if so, they gave us the deck and we'll pick the card   if (typeof x == "object") {     let pickedCard = Math.floor(Math.random() * x.length);     return pickedCard;   }   // Otherwise just let them pick the card   else if (typeof x == "number") {     let pickedSuit = Math.floor(x / 13);     return { suit: suits[pickedSuit], card: x % 13 };   } }  let myDeck = [   { suit: "diamonds", card: 2 },   { suit: "spades", card: 10 },   { suit: "hearts", card: 4 }, ];  let pickedCard1 = myDeck[pickCard(myDeck)]; alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);  let pickedCard2 = pickCard(15); alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

使用 TypeScript 4.1,某些情況下賦值將會失敗,而某些情況下的重載解析則將失敗。解決方法是,最好使用類型斷言來避免錯誤。

到此,關(guān)于“TypeScript 4.1中的模板字面類型是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
文章題目:TypeScript4.1中的模板字面類型是什么
新聞來源:http://weahome.cn/article/jjgsii.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部