<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.0正式發(fā)布!現(xiàn)在是開始使用它的最佳時(shí)機(jī)

          共 9061字,需瀏覽 19分鐘

           ·

          2020-08-28 06:40

          作者 | Daniel Rosenwasser
          譯者 | 王強(qiáng)
          策劃 | 李俊辰
          今天,微軟宣布 TypeScript 4.0 正式版上線了!這一新版本深入改進(jìn)了表現(xiàn)力、生產(chǎn)力和可伸縮性,是 TypeScript 語言的新一代版本。

          如果你還不熟悉 TypeScript,這里簡單介紹一下:它是一種在 JavaScript 之上通過添加靜態(tài)類型語法來構(gòu)建的語言。它的基本理念是,記下值的類型以及它們的使用位置后,可以使用 TypeScript 對代碼進(jìn)行類型檢查,并在運(yùn)行代碼之前(甚至在保存文件之前)告訴你代碼錯(cuò)誤的相關(guān)信息。然后,你可以使用 TypeScript 編譯器從代碼中剝離類型,并為你提供可在任何地方運(yùn)行的簡潔易讀的 JavaScript 代碼。除了類型檢查之外,TypeScript 還使用靜態(tài)類型來支持強(qiáng)大的編輯器工具,例如自動完成、代碼導(dǎo)航、重構(gòu)等。實(shí)際上,如果你在 Visual Studio Code 或 Visual Studio 這樣的編輯器中使用過 JavaScript,那么你已經(jīng)用上了類型和 TypeScript 帶來的體驗(yàn)。可以在我們的網(wǎng)站上了解更多相關(guān)信息。

          https://www.typescriptlang.org/

          TypeScript 4.0 沒有引入特別重大的更改。實(shí)際上,如果你剛剛開始接觸這種語言,那么現(xiàn)在是開始使用它的最佳時(shí)機(jī)。它的社區(qū)已經(jīng)成熟完善,并在不斷發(fā)展,擁有可運(yùn)行的代碼和很棒的新資源可供學(xué)習(xí)。還有一件事情:盡管我們?yōu)?4.0 引入了那么多好東西,但你實(shí)際上只需要了解 TypeScript 的基礎(chǔ)知識就可以開始生產(chǎn)應(yīng)用了!

          如果你已經(jīng)在項(xiàng)目中使用 TypeScript,則可以通過 NuGet 獲取它,也可以通過以下命令使用 npm 獲取:
          npm install?-D typescript

          你還可以通過以下方式獲得編輯器支持:

          • 下載 Visual Studio 2019/2017:

            • https://marketplace.visualstudio.com/items?itemName=TypeScriptTeam.TypeScript-40

          • 安裝 Visual Studio Code 的內(nèi)部版本,或按照以下說明使用較新版本的 TypeScript。

            • https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-newer-typescript-versions

          4.0 之旅?

          TypeScript 是當(dāng)今許多人的 JavaScript 技術(shù)棧的核心部分。在 npm 上,TypeScript 在 7 月首次實(shí)現(xiàn)了超過 5000 萬的月下載量!盡管我們知道它總有增長和改進(jìn)的余地,但很明顯,大多數(shù)使用 TypeScript 編碼的開發(fā)人員確實(shí)很喜歡它。StackOverflow 的最新開發(fā)人員調(diào)查將 TypeScript 列為第二受歡迎的語言。在最新的 JS 現(xiàn)狀調(diào)查中,使用 TypeScript 的開發(fā)人員中有大約 89% 表示會再次使用它。

          值得一提的是我們走到今天所走過的旅程。在之前的兩個(gè)主要版本中,我們回顧了多年來閃耀的一些亮點(diǎn)。對于 TypeScript 4.0,我們將保持這種傳統(tǒng)。

          從 3.0 版本向前看,可以看到許多令人眼花繚亂的更改,但是 TypeScript 3.0 本身就產(chǎn)生了很大的沖擊。統(tǒng)一元組類型和參數(shù)列表是當(dāng)時(shí)的一大亮點(diǎn),可在函數(shù)上啟用大量已有的 JavaScript 模式。這個(gè)發(fā)行版還提供了項(xiàng)目參考,以幫助擴(kuò)展、組織和共享代碼庫。3.0 版的一個(gè)產(chǎn)生重大影響的小更改是對 any 引入了類型安全的替代方法,稱為 unknown。

          TypeScript 3.1 擴(kuò)展了映射類型的功能以處理元組和數(shù)組類型,并極大簡化了將屬性附加到函數(shù)的過程,而無需使用 TypeScript 專屬的運(yùn)行時(shí)功能(已停用)。

          TypeScript 3.2 允許對象在泛型類型上傳播,并通過嚴(yán)格類型化 bind、call 和 apply,利用 3.0 的功能更好地建模函數(shù)的元編程。TypeScript 3.3 更多關(guān)注穩(wěn)定性,但也改進(jìn)了聯(lián)合類型方法,并在 --build 模式下添加了文件增量式構(gòu)建。

          在 3.4 版本中,我們進(jìn)一步支持函數(shù)式模式,更好地支持不可變數(shù)據(jù)結(jié)構(gòu),并改進(jìn)了對高階泛型函數(shù)的推斷。這個(gè)發(fā)行版的一大改進(jìn)是引入了 --incremental 標(biāo)志,該方法避免了在每次 TypeScript 運(yùn)行時(shí)完全重建,從而加快了編譯和類型檢查的速度。

          在 TypeScript 3.5 和 3.6 中加強(qiáng)了一些類型系統(tǒng)規(guī)則,還帶來了更智能的兼容性檢查規(guī)則。

          TypeScript 3.7 是一個(gè)非常值得關(guān)注的版本,因?yàn)樗芎玫亟Y(jié)合了許多新的類型系統(tǒng)特性與 ECMAScript 特性。在類型系統(tǒng)方面,我們加入了遞歸類型別名引用和對斷言樣式函數(shù)的支持,這兩者都是獨(dú)特的類型系統(tǒng)特性。從 JavaScript 方面來看,該版本帶來了可選鏈和空值合并功能,這是 TypeScript 和 JavaScript 用戶最期待的兩項(xiàng)功能。

          最近,3.8 和 3.9 帶來了僅類型的導(dǎo)入 / 導(dǎo)出,以及許多 ECMAScript 特性,例如私有字段、模塊中的頂級 await 和新的 export* 語法。這些版本還帶來了性能和可伸縮性優(yōu)化。

          我們還沒有提到關(guān)于語言服務(wù)、基礎(chǔ)架構(gòu)、網(wǎng)站和其他核心項(xiàng)目中的那些工作,這些工作對于 TypeScript 的體驗(yàn)非常關(guān)鍵。核心團(tuán)隊(duì)的項(xiàng)目之外,我們在生態(tài)系統(tǒng)中還有非常出色的貢獻(xiàn)者社區(qū),他們推動了體驗(yàn)的不斷改進(jìn),并通過 DefinitelyTyped 甚至 TypeScript 本身提供了幫助。在 2012 年剛開始時(shí),DefinitelyTyped 僅有 80 個(gè)拉取請求。在 2019 年,它有超過 8300 個(gè)拉取請求,非常震撼人心。這些貢獻(xiàn)是 TypeScript 體驗(yàn)的基礎(chǔ),這樣一個(gè)繁忙而熱情的社區(qū)在不斷改善我們的生態(tài)系統(tǒng),并推動我們不斷改進(jìn),我們對此表示感謝。

          可變元組類型
          考慮 JavaScript 中稱為 concat 的函數(shù),該函數(shù)接收兩個(gè)數(shù)組或元組類型,并將它們連接在一起以創(chuàng)建一個(gè)新數(shù)組。
          function?concat(arr1, arr2)?{
          ????return?[...arr1, ...arr2];
          }
          考慮 tail,它接收一個(gè)數(shù)組或元組,并返回除第一個(gè)元素外的所有元素。
          function?tail(arg)?{
          ????const?[_, ...result] = arg;
          ????return?result
          }
          我們?nèi)绾卧?TypeScript 中為它們類型化?對于 concat,我們在較舊版本的 TS 中唯一可以做的就是嘗試編寫一些重載。
          function?concat<>(arr1: [], arr2: []): [A];
          function?concat<A>(arr1: [A], arr2: []): [A];
          function?concat<A, B>(arr1: [A, B], arr2: []): [A, B];
          function?concat<A, B, C>(arr1: [A, B, C], arr2: []): [A, B, C];
          function?concat<A, B, C, D>(arr1: [A, B, C, D], arr2: []): [A, B, C, D];
          function?concat<A, B, C, D, E>(arr1: [A, B, C, D, E], arr2: []): [A, B, C, D, E];
          function?concat<A, B, C, D, E, F>(arr1: [A, B, C, D, E, F], arr2: []): [A, B, C, D, E, F];)
          第二個(gè)數(shù)組始終為空時(shí)會冒出來七個(gè)重載。當(dāng) arr2 有一個(gè)參數(shù)時(shí)我們再加一些看看。
          function?concat<A2>(arr1: [], arr2: [A2]): [A2];
          function?concat<A1, A2>(arr1: [A1], arr2: [A2]): [A1, A2];
          function?concat<A1, B1, A2>(arr1: [A1, B1], arr2: [A2]): [A1, B1, A2];
          function?concat<A1, B1, C1, A2>(arr1: [A1, B1, C1], arr2: [A2]): [A1, B1, C1, A2];
          function?concat<A1, B1, C1, D1, A2>(arr1: [A1, B1, C1, D1], arr2: [A2]): [A1, B1, C1, D1, A2];
          function?concat<A1, B1, C1, D1, E1, A2>(arr1: [A1, B1, C1, D1, E1], arr2: [A2]): [A1, B1, C1, D1, E1, A2];
          function?concat<A1, B1, C1, D1, E1, F1, A2>(arr1: [A1, B1, C1, D1, E1, F1], arr2: [A2]): [A1, B1, C1, D1, E1, F1, A2];
          很明顯這變得越來越離譜了。不幸的是,在類型化 tail 之類的函數(shù)時(shí),你也會遇到同樣的問題。下面是另一種情況,我們稱之為“被一千個(gè)重載搞垮”,它甚至什么問題都解決不了。它只為我們想寫的重載提供正確的類型(不管重載有多少)。如果我們想做一個(gè)通行模式,就需要下面這種重載:
          function?concat<T, U>(arr1: T[], arr2, U[]): Array<T?| U>;

          但在使用元組時(shí),這個(gè)簽名不會包含輸入長度或元素順序的任何信息。TypeScript 4.0 帶來了兩個(gè)基礎(chǔ)更改,并在推斷方面進(jìn)行了改進(jìn),從而可以類型化這些內(nèi)容。

          第一個(gè)更改是元組類型語法中的 spread 現(xiàn)在可以泛型。這意味著即使我們不知道要操作的實(shí)際類型,也可以表示對元組和數(shù)組的高階操作。在這些元組類型中實(shí)例化泛型 spread(或用真實(shí)類型替換)時(shí),它們可以產(chǎn)生其他數(shù)組和元組類型集。

          例如,我們可以類型化 tail 那樣的函數(shù),而不會出現(xiàn)“被一千個(gè)重載搞垮”的問題。
          function?tail<T?extends?any[]>(arr: readonly [any, ...T]) {
          ????const?[_ignored, ...rest] = arr;
          ????return?rest;
          }
          const?myTuple = [1, 2, 3, 4] as?const;
          const?myArray = ["hello", "world"];
          // type [2, 3, 4]
          const?r1 = tail(myTuple);
          // type [2, 3, ...string[]]
          const?r2 = tail([...myTuple, ...myArray] as?const);
          第二個(gè)更改是,rest 元素可以出現(xiàn)在元組中的任何位置,而不僅僅是在結(jié)尾!
          type?Strings = [string, string];
          type?Numbers = [number, number];
          // [string, string, number, number]
          type?StrStrNumNum = [...Strings, ...Numbers];
          以前,TypeScript 會發(fā)出如下錯(cuò)誤。
          A rest element must be?last?in a?tuple type.

          但是現(xiàn)在這種限制取消了。

          當(dāng)我們在沒有已知長度的類型中 spread 時(shí),結(jié)果類型也將變得不受限制,并且后面的所有元素都會變?yōu)榻Y(jié)果的 rest 元素類型。
          type?Strings = [string, string];
          type?Numbers = number[]
          // [string, string, ...Array]
          type?Unbounded = [...Strings, ...Numbers, boolean];
          將這兩種行為結(jié)合在一起,我們可以為 concat 編寫一個(gè)類型良好的簽名:
          type?Arr = readonly any[];
          function?concat<T?extends?Arr, U?extends?Arr>(arr1: T, arr2: U): [...T, ...U] {
          ????return?[...arr1, ...arr2];
          }

          盡管一個(gè)簽名仍然有些冗長,但它畢竟只有一個(gè),只需寫一次,并且在所有數(shù)組和元組上都具有可預(yù)測的行為。

          這個(gè)功能很棒,在其他更復(fù)雜的場景中更有用。例如,考慮一個(gè)函數(shù)來部分應(yīng)用參數(shù),名為 partialCall。partialCall 接收一個(gè)函數(shù)(這里就叫 f)以及該函數(shù)期望的幾個(gè)初始參數(shù)。然后,它返回一個(gè)新函數(shù),接收它需要的其他所有參數(shù),收到后調(diào)用 f。
          function?partialCall(f, ...headArgs) {
          ????return?(...tailArgs) =>?f(...headArgs, ...tailArgs)
          }
          TypeScript 4.0 改進(jìn)了 rest 參數(shù)和 rest 元組元素的推斷過程,因此我們可以類型化它并使其“正常工作”。
          type Arr = readonly unknown[];
          function?partialCall<T?extends?Arr, U?extends?Arr, R>(f: (...args: [...T, ...U])?=> R, ...headArgs: T)?{
          ????return?(...b: U) => f(...headArgs, ...b)
          }
          在這種情況下,partialCall 會知道其最初可以使用和不能使用哪些參數(shù),并返回一個(gè)可以正確接收和拒絕剩余內(nèi)容的函數(shù)。
          const?foo = (x: string, y: number, z: boolean) =>?{}
          // This doesn't work because we're feeding in the wrong type for 'x'.
          const?f1 = partialCall(foo, 100);
          // ~~~
          // error! Argument of type 'number' is not assignable to parameter of type 'string'.

          // This doesn't work because we're passing in too many arguments.
          const?f2 = partialCall(foo, "hello", 100, true, "oops")
          // ~~~~~~
          // error! Expected 4 arguments, but got 5.

          // This works! It has the type '(y: number, z: boolean) => void'
          const?f3 = partialCall(foo, "hello");
          // What can we do with f3 now?
          f3(123, true); // works!
          f3();
          // error! Expected 2 arguments, but got 0.
          f3(123, "hello");
          // ~~~~~~~
          // error! Argument of type '"hello"' is not assignable to parameter of type 'boolean'.

          可變元組類型創(chuàng)造了許多新模式,尤其是在函數(shù)組合方面。我們希望利用它來改善對 JavaScript 內(nèi)置的 bind 方法的類型檢查。此外還有其他一些推斷改進(jìn)和模式,想了解更多信息,可以查看可變元組的拉取請求。

          https://github.com/microsoft/TypeScript/pull/39094

          標(biāo)記的元組元素

          改善元組類型和參數(shù)列表的體驗(yàn)很重要,因?yàn)樗刮覀兡軌驀@常見的 JavaScript 習(xí)慣用法進(jìn)行強(qiáng)類型驗(yàn)證——實(shí)際上只是對參數(shù)列表進(jìn)行切片和切塊,并將它們傳遞給其他函數(shù)。對 rest 參數(shù)使用元組類型是其中的關(guān)鍵。

          例如,以下函數(shù)使用元組類型作為 rest 參數(shù):
          function?foo(...args: [string, number]): void?{
          ????// ...
          }
          應(yīng)該與以下函數(shù)沒有區(qū)別。
          function?foo(arg0: string, arg1: number): void?{
          ????// ...
          }
          對于 foo 的任何調(diào)用者。
          foo("hello", 42); // works
          foo("hello", 42, true); // error
          foo("hello"); // error
          不過可讀性就有區(qū)別了。在第一個(gè)示例中,我們沒有第一個(gè)和第二個(gè)元素的參數(shù)名稱。盡管這些對類型檢查沒有影響,但元組位置上缺少標(biāo)記會難以傳達(dá)我們的意圖。因此,在 TypeScript 4.0 中,元組類型現(xiàn)在可以提供標(biāo)記。
          type Range = [start: number, end: number];
          為了進(jìn)一步加強(qiáng)參數(shù)列表和元組類型之間的聯(lián)系,我們讓 rest 元素和可選元素的語法與參數(shù)列表的語法一致。
          type?Foo = [first: number, second?: string, ...rest: any[]];
          標(biāo)記元組使用時(shí)有些規(guī)則,其中一條是:在標(biāo)記一個(gè)元組元素時(shí),還必須標(biāo)記元組中的所有其他元素。
          type?Bar = [first: string, number];
          // ~~~~~~
          // error! Tuple members must all have names or all not have names.
          值得注意的是,在解構(gòu)時(shí)標(biāo)記不需要我們用不同的名稱命名變量。它們純粹是為文檔和工具鏈服務(wù)的。
          function?foo(x: [first: string, second: number]) {
          ????// ...
          ????// note:?we didn't need to name these 'first' and 'second'
          ????let?[a, b] = x;
          ????// ...
          }

          總的來說,當(dāng)利用圍繞元組和參數(shù)列表的模式,并以類型安全的方式實(shí)現(xiàn)重載時(shí),帶標(biāo)記的元組非常方便好用。實(shí)際上,TypeScript 的編輯器支持會在可能的情況下將它們顯示為重載。

          了解更多信息,請查看帶標(biāo)記的元組元素的拉取請求。

          https://github.com/microsoft/TypeScript/pull/38234

          構(gòu)造器的類屬性推斷
          當(dāng)啟用 noImplicitAny 時(shí),TypeScript 4.0 現(xiàn)在可以使用控制流分析來確定類中屬性的類型。
          class?Square {
          ????// Previously: implicit any!
          ????// Now: inferred to `number`!
          ????area;
          ????sideLength;
          ????constructor(sideLength: number) {
          ????????this.sideLength = sideLength;
          ????????this.area = sideLength ** 2;
          ????}
          }
          如果構(gòu)造器的路徑并非都分配給一個(gè)實(shí)例成員,則該屬性可能被認(rèn)為是 undefined 的。
          class?Square {
          ????sideLength;
          ????constructor(sideLength: number) {
          ????????if?(Math.random()) {
          ????????????this.sideLength = sideLength;
          ????????}
          ????}
          ????get?area() {
          ????????return?this.sideLength ** 2;
          ????????// ~~~~~~~~~~~~~~~
          ????????// error! Object is possibly 'undefined'.
          ????}
          }
          如果你更了解某些情況(例如,你擁有某種 initialize 方法),則當(dāng)你處于 strictPropertyInitialization 中時(shí),需要使用顯式類型注釋以及明確的賦值斷言(!)。
          class?Square {
          ????// definite assignment assertion
          ????// v
          ????sideLength!: number;
          ????// ^^^^^^^^
          ????// type annotation
          ????constructor(sideLength: number) {
          ????????this.initialize(sideLength)
          ????}
          ????initialize(sideLength: number) {
          ????????this.sideLength = sideLength;
          ????}
          ????get?area() {
          ????????return?this.sideLength ** 2;
          ????}
          }

          更多信息請見拉取請求。

          https://github.com/microsoft/TypeScript/pull/379200

          短路賦值運(yùn)算符
          JavaScript 和許多語言都支持一組稱為"復(fù)合賦值運(yùn)算符"的運(yùn)算符。復(fù)合賦值運(yùn)算符將一個(gè)運(yùn)算符應(yīng)用于兩個(gè)參數(shù),然后將結(jié)果賦給左側(cè)。你可能以前看過這些:
          // Addition
          // a = a + b
          a += b;
          // Subtraction
          // a = a - b
          a -= b;
          // Multiplication
          // a = a * b
          a *= b;
          // Division
          // a = a / b
          a /= b;
          // Exponentiation
          // a = a ** b
          a **= b;
          // Left Bit Shift
          // a = a << b
          a <<= b;

          JavaScript 中有很多運(yùn)算符都有對應(yīng)的賦值運(yùn)算符!但是有三個(gè)值得注意的例外:邏輯和(&&),邏輯或(||)和空值合并(??)。

          所以 TypeScript 4.0 支持了一個(gè)新的 ECMAScript 特性,添加了三個(gè)新的賦值運(yùn)算符:&&=,||= 和 ??= 。

          這些運(yùn)算符非常適合替換下面這種代碼示例:
          a?= a && b;
          a?= a || b;
          a?= a ?? b;
          或者像下面這樣的 if 代碼段:
          // could be 'a ||= b'
          if?(!a) {
          ????a = b;
          }
          我們甚至看到了一些模式,可以在需要時(shí)懶惰地初始化值。
          let?values: string[];
          // Before
          (values ?? (values = [])).push("hello");
          // After
          (values ??= []).push("hello");
          在極少數(shù)情況下,你使用帶有副作用的 getter 或 setter 時(shí),需要注意的是這些運(yùn)算符僅在必要時(shí)執(zhí)行賦值。從這個(gè)意義上講,"短路"的不僅是運(yùn)算符的右側(cè),賦值本身也短路了。
          obj.prop ||= foo();
          //?roughly equivalent to either of the following
          obj.prop ||?(obj.prop = foo());
          if?(!obj.prop) {
          ????obj.prop = foo();
          }
          可以試著運(yùn)行 這個(gè)示例,看看它和總是執(zhí)行賦值有什么區(qū)別。
          const?obj = {
          ????get?prop() {
          ????????console.log("getter has run");
          ????????// Replace me!
          ????????return?Math.random() < 0.5;
          ????},
          ????set?prop(_val: boolean) {
          ????????console.log("setter has run");
          ????}
          };
          function?foo() {
          ????console.log("right side evaluated");
          ????return?true;
          }
          console.log("This one always runs the setter");
          obj.prop = obj.prop || foo();
          console.log("This one *sometimes* runs the setter");
          obj.prop ||= foo();

          有關(guān)更多細(xì)節(jié)可以查看拉取請求。

          https://github.com/microsoft/TypeScript/pull/37727

          你也可以查看 TC39 的提案存儲庫。

          https://github.com/tc39/proposal-logical-assignment/

          catch 子句綁定支持 unknown
          自 TypeScript 誕生以來,catch 子句變量始終按 any 類型化。這意味著 TypeScript 允許你對它們進(jìn)行任何操作。
          try?{
          ????// ...
          }
          catch?(x) {
          ????// x has type 'any' - have fun!
          ????console.log(x.message);
          ????console.log(x.toUpperCase());
          ????x++;
          ????x.yadda.yadda.yadda();
          }
          上述代碼會有一些無法預(yù)期的行為!由于這些變量默認(rèn)情況下的類型為 any,因此它們沒有任何類型安全性可以防止無效操作。因此,TypeScript 4.0 現(xiàn)在允許你將 catch 子句變量的類型指定為 unknown。unknown 比 any 更安全,因?yàn)樗鼤谖覀儾僮髦抵疤嵝盐覀儓?zhí)行某種類型檢查。
          try?{
          ????// ...
          }
          catch?(e: unknown) {
          ????// error!
          ????// Property 'toUpperCase' does not exist on type 'unknown'.
          ????console.log(e.toUpperCase());
          ????if?(typeof?e === "string") {
          ????????// works!
          ????????// We've narrowed 'e' down to the type 'string'.
          ????????console.log(e.toUpperCase());
          ????}
          }

          盡管默認(rèn)情況下 catch 變量的類型不會更改,但我們將來可能會考慮使用新的 --strict 模式標(biāo)志,以便用戶選擇啟用此行為。同時(shí),應(yīng)該可以編寫一個(gè) lint 規(guī)則來強(qiáng)制 catch 變量具有如下顯式注解之一:: any 或: unknown。

          有關(guān)更多信息,可以查看拉取請求。

          https://github.com/microsoft/TypeScript/pull/39015

          定制 JSX 工廠

          使用 JSX 時(shí),fragment 是 JSX 元素的一種,允許我們返回多個(gè)子元素。當(dāng)我們第一次在 TypeScript 中實(shí)現(xiàn) fragment 時(shí),我們對其他庫如何利用它們并不了解。如今,大多數(shù)鼓勵(lì)使用 JSX 和支持 fragment 的庫都具有類似的 API 設(shè)計(jì)。

          在 TypeScript 4.0 中,用戶可以通過新的 jsxFragmentFactory 選項(xiàng)來自定義 fragment 工廠。

          例如,以下 tsconfig.json 文件告訴 TypeScript 以與 React 兼容的方式轉(zhuǎn)換 JSX,但將每個(gè)工廠調(diào)用(invocation)切換為 h 而不是 React.createElement,并使用 Fragment 而不是 React.Fragment。
          {
          ??"compilerOptions": {
          ????"target": "esnext",
          ????"module": "commonjs",
          ????"jsx": "react",
          ????"jsxFactory": "h",
          ????"jsxFragmentFactory": "Fragment"
          ??}
          }
          如果需要基于各個(gè)文件使用不同的 JSX 工廠,則可以利用新的 /**?@jsxFrag */ 注釋。例如,下面的內(nèi)容:
          // Note:?these pragma comments need to be written
          // with a JSDoc-style multiline syntax to take effect.
          /** @jsx h */
          /** @jsxFrag Fragment */
          import?{ h, Fragment } from?"preact";
          let?stuff = <>
          ????<div>Hellodiv>
          ;
          將輸出成這樣的 JavaScript:
          // Note:?these pragma comments need to be written
          // with a JSDoc-style multiline syntax to take effect.
          /** @jsx h */
          /** @jsxFrag Fragment */
          import?{ h, Fragment } from?"preact";
          let?stuff = h(Fragment, null,
          ????h("div", null, "Hello"));

          查看拉取請求以獲取更多信息。

          https://github.com/microsoft/TypeScript/pull/38720

          加快了 build 模式的速度

          以前,使用 --noEmitOnError 標(biāo)志時(shí),當(dāng)先前的編譯在 --incremental 下出現(xiàn)錯(cuò)誤,編譯速度將非常緩慢。這是因?yàn)榛?--noEmitOnError 標(biāo)志,上次編譯的任何信息都不會緩存在.tsbuildinfo 文件中。

          TypeScript 4.0 對此進(jìn)行了更改,從而在這些情況下極大地提高了速度,進(jìn)而改進(jìn)了 --build 模式的場景(這意味著同時(shí)有 --incremental 和 --noEmitOnError)。

          有關(guān)詳細(xì)信息,請查看拉取請求。

          https://github.com/microsoft/TypeScript/pull/38853

          帶有 --noEmit 的 --incremental

          TypeScript 4.0 允許我們在利用 --incremental 編譯時(shí)使用 --noEmit 標(biāo)志。以前不允許這樣做,因?yàn)?--incremental 需要發(fā)出.tsbuildinfo 文件。

          有關(guān)詳細(xì)信息,請查看拉取請求。

          https://github.com/microsoft/TypeScript/pull/39122

          編輯器改進(jìn)

          TypeScript 編譯器不僅可以為大多數(shù)主流編輯器提供較好的 TS 編輯體驗(yàn),還可以改進(jìn) Visual Studio 系列編輯器的 JavaScript 開發(fā)體驗(yàn)。

          根據(jù)你使用的編輯器,在編輯器中使用新的 TypeScript/JavaScript 功能時(shí)會有區(qū)別:

          • Visual Studio Code 支持選擇不同版本的 TypeScript。另外,還有 JavaScript/TypeScript Nightly Extension 來緊跟最新版本(通常非常穩(wěn)定)。

          • Visual Studio 2017/2019 有上面的 SDK 安裝程序和 MSBuild 安裝。

          更多信息見 TS 編輯器支持列表。

          https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support

          轉(zhuǎn)換為可選鏈

          可選鏈?zhǔn)且豁?xiàng)新功能,受到了廣泛的歡迎。TypeScript 4.0 在轉(zhuǎn)換常見模式時(shí)可以利用可選鏈和空值合并的優(yōu)勢!

          我們認(rèn)為這種重構(gòu)應(yīng)該能捕獲大多數(shù)用例的意圖,尤其是當(dāng) TypeScript 對你的類型有更精確的了解時(shí)。

          有關(guān)詳細(xì)信息,請查看拉取請求。

          https://github.com/microsoft/TypeScript/pull/39135

          /** @deprecated */ 支持

          現(xiàn)在,TypeScript 的編輯支持可以識別聲明中是否帶有/** @deprecated*/ JSDoc 注釋。該信息顯示在自動完成列表中,并作為編輯器可以特別處理的建議診斷。在像 VSCode 這樣的編輯器中,deprecated 的值通常顯示為刪除線樣式。

          有關(guān)詳細(xì)信息,查看拉取請求。

          https://github.com/microsoft/TypeScript/pull/38523

          啟動時(shí)的部分編輯模式

          很多用戶抱怨啟動時(shí)間緩慢,尤其是在大型項(xiàng)目中。具體來說,罪魁禍?zhǔn)淄ǔJ且粋€(gè)稱為項(xiàng)目加載的過程,該過程與我們編譯器的程序構(gòu)建步驟大致相同。這一過程從一組初始文件開始,解析它們、解析它們的依賴、再解析那些依賴,解析那些依賴的依賴,等等,最后需要花費(fèi)很長時(shí)間。項(xiàng)目越大,啟動延遲可能會越長。

          所以我們一直在努力為開發(fā)人員提供一種新的模式,在獲得完整的語言服務(wù)體驗(yàn)之前提供部分體驗(yàn)。這里的核心思想是,編輯者可以運(yùn)行僅具有單個(gè)文件視圖的輕量級部分服務(wù)器。

          這種新模式可以將 TypeScript 在代碼庫上開始交互之前的準(zhǔn)備時(shí)間從 20 秒到 1 分鐘縮短到只有幾秒鐘。比如說,在較大的代碼庫上重啟編輯器時(shí),TS 3.9 版沒法立即提供自動完成和快速信息;另一方面,TS 4.0 可以立即提供完整的編輯體驗(yàn),同時(shí)在后臺加載整個(gè)項(xiàng)目。

          當(dāng)前,唯一支持此模式的編輯器是 Visual Studio Code,但 UX 和功能仍有改進(jìn)的余地。我們列出了準(zhǔn)備加入的改進(jìn),希望獲得更多反饋。

          https://github.com/microsoft/TypeScript/issues/39035

          有關(guān)更多信息,你可以查看原始提案,拉取請求,以及后續(xù)的 meta 問題。

          https://github.com/microsoft/TypeScript/issues/37713

          更智能的自動導(dǎo)入

          自動導(dǎo)入是一個(gè)了不起的功能。但是,自動導(dǎo)入在用 TypeScript 編寫的包上不起作用——也就是說,我們得在項(xiàng)目的其他位置至少寫了一個(gè)顯式導(dǎo)入。

          為什么自動導(dǎo)入適用于 @types 軟件包,而不適用于使用自己類型的包呢?其實(shí)自動導(dǎo)入是通過檢查項(xiàng)目中已經(jīng)包含的軟件包來實(shí)現(xiàn)的。TypeScript 有一個(gè)怪癖,可以自動包括 node_modules/@types 中的所有包,而忽略其他包;但爬取所有 node_modules 包的開銷可能會很昂貴。

          當(dāng)你嘗試自動導(dǎo)入剛剛安裝但尚未使用的內(nèi)容時(shí),這些都會導(dǎo)致糟糕的體驗(yàn)。

          TypeScript 4.0 現(xiàn)在可以包含你在 package.json 的 dependencies(和 peerDependencies)字段中列出的包。這些包中的信息僅用于改進(jìn)自動導(dǎo)入,不會更改類型檢查等其他內(nèi)容。這樣就避免了遍歷 node_modules 目錄的成本,使我們可以為所有帶類型的依賴項(xiàng)提供自動導(dǎo)入。

          當(dāng)你的 package.json 列出了超過十項(xiàng)尚未導(dǎo)入的類型化依賴項(xiàng)時(shí),這個(gè)功能會自動禁用,以避免緩慢的項(xiàng)目加載過程。要強(qiáng)制開啟它或完全禁用它,你可以配置編輯器。在 Visual Studio Code 中是"Include Package JSON Auto Imports"設(shè)置(或 typescript.preferences.includePackageJsonAutoImports)。

          有關(guān)詳細(xì)信息,可以查看提案問題以及拉取請求。

          https://github.com/microsoft/TypeScript/issues/37812

          我們的新網(wǎng)站!

          TypeScript 網(wǎng)站最近被徹底重寫了!

          詳細(xì)信息可以參考之前的文章:

          《TypeScript 新版網(wǎng)站上線:帶來了新的導(dǎo)航機(jī)制》

          重大更改
          lib.d.ts

          我們的 lib.d.ts 聲明已更改,具體來說是 DOM 的類型已更改。主要是刪除了 document.origin,它僅在 IE 的舊版本中有效,而 Safari MDN 建議改用 self.origin。

          屬性重寫訪問器(反之亦然)是錯(cuò)誤
          以前,只有在使用 useDefineForClassFields 時(shí),屬性重寫訪問器或訪問器重寫屬性是一個(gè)錯(cuò)誤;但現(xiàn)在,在派生類中聲明一個(gè)將重寫基類中的 getter 或 setter 的屬性時(shí)總是發(fā)出錯(cuò)誤。

          class?Base?{
          ????get foo() {
          ????????return?100;
          ????}
          ????set foo() {
          ????????//?...
          ????}
          }
          class?Derived?extends?Base?{
          ????foo = 10;
          //??~~~
          //?error!
          //?'foo'?is?defined as?an accessor in?class?'Base',
          //?but is?overridden here in?'Derived'?as?an instance property.
          }

          class?Base?{
          ????prop = 10;
          }
          class?Derived?extends?Base?{
          ????get prop()?{
          ????// ~~~~
          ????// error!
          ????// 'prop' is defined as a property in class 'Base', but is overridden here in 'Derived' as an accessor.
          ????????return?100;
          ????}
          }

          有關(guān)詳細(xì)信息,查看拉取請求。

          https://github.com/microsoft/TypeScript/pull/37894

          delete 的操作數(shù)必須是可選的
          在 strictNullChecks 中使用 delete 運(yùn)算符時(shí),操作數(shù)現(xiàn)在必須為 any、unknown、never 或?yàn)榭蛇x(因?yàn)樗陬愋椭邪?undefined)。否則,使用 delete 運(yùn)算符是錯(cuò)誤的。
          interface?Thing {
          ????prop: string;
          }
          function?f(x: Thing) {
          ????delete?x.prop;
          ????// ~~~~~~
          ????// error! The operand of a 'delete' operator must be optional.
          }

          關(guān)于更多信息,查看拉取請求。

          https://github.com/microsoft/TypeScript/pull/37921

          TypeScript 的 Node 工廠用法已棄用

          如今,TypeScript 提供了一組用于生成 AST 節(jié)點(diǎn)的“工廠”函數(shù)。但是,TypeScript 4.0 提供了新的 node 工廠 API。因此 TypeScript 4.0 決定棄用使用這些舊函數(shù),推薦改用新函數(shù)。

          有關(guān)更多信息,請查看拉取請求。

          https://github.com/microsoft/TypeScript/pull/35282

          下一步計(jì)劃

          TypeScript 4.1 的迭代計(jì)劃已經(jīng)上線了,你可以大致了解一下。

          https://github.com/microsoft/TypeScript/issues/40124

          同時(shí),你可以在工作區(qū)或編輯器中使用 nightly 構(gòu)建來預(yù)覽 4.1 中添加的新特性。無論你是在使用 TypeScript 4.0 還是下一版本,我們都希望聽到你的反饋!可以通過 Twitter 聯(lián)系我們,或在 GitHub 上發(fā)起問題。

          我們再一次為社區(qū)所做的一切工作和奉獻(xiàn)精神深表感謝。我們希望讓 TypeScript 和 JavaScript 的編碼體驗(yàn)成為你應(yīng)得的純粹樂趣。為此,我們需要改善語言和編輯體驗(yàn)、提升性能、迭代我們的用戶體驗(yàn)、降低入門和學(xué)習(xí)的門檻等等。

          非常感謝大家,請享用 4.0 版本吧,編程愉快!

          延伸閱讀

          https://devblogs.microsoft.com/typescript/announcing-typescript-4-0/

          瀏覽 51
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  五月天av在线 | 欧美 日韩 国产 中文 | 大香蕉伊人手机在线 | 激情一区二区三区欧美 | 水密桃视频网站 |