原文連接 Announcing TypeScript 3.8 by Daniel,本文參考翻譯了部分原文javascript
TypeScript近期更新了3.8版本,帶來了許多新特性java
這個特性可能平時你們基本用不到,可是若是碰到過相似問題的話你們可能對這個會感興趣一些(尤爲是在--iosolateModules下變編譯,或者使用transplieModule API, 或者Babel)ios
問題出現的緣由是Typescript在引用類型的時候複用了Javascript的import語法。git
// ./foo.ts
interface Options {
// ...
}
export function doThing(options: Options) {
// ...
}
// ./bar.ts
import { doThing, Options } from "./foo.js";
function doThingBetter(options: Options) {
// do something twice as good
doThing(options);
doThing(options);
}
複製代碼
這樣導入doThing和Options很方便,由於大多數狀況下咱們不關心導入的具體內容,只知道導入了一些東西。不幸的是代碼能夠正常運行是由於一個被稱爲導入省略(import elision)的特性,它發現Options是一個類型,而後自動去掉了它的導入。真正的執行結果是:github
// ./foo.js
export function doThing(options: Options) {
// ...
}
// ./bar.js
import { doThing } from "./foo.js";
function doThingBetter(options: Options) {
// do something twice as good
doThing(options);
doThing(options);
}
複製代碼
也許這也不能引發你的注意,可是當代碼是如下這種狀況的時候會出現混亂typescript
import { MyThing } from "./some-module.js";
export { MyThing };
複製代碼
咱們根本沒法肯定MyThing是不是一個類型async
爲了不出現相似狀況,TypeScript3.8 添加了一個新的類型導入和導出的語法,以下:函數
import type { SomeThing } from "./some-module.js";
export type { SomeThing };
複製代碼
須要注意的是import type 只是爲了註釋和申明,它會被刪除,在運行時無任何意義fetch
Typescript3.8 提供了ECMAScript私有屬性(ECMAScript’s private fields),這個特性是stage-3 class fields proposal的一部分。ui
class Person {
#name: string
constructor(name: string) {
this.#name = name;
}
greet() {
console.log(`Hello, my name is ${this.#name}!`);
}
}
let jeremy = new Person("Jeremy Bearimy");
jeremy.#name
// ~~~~~
// 屬性 '#name' 不能在類Person 外訪問
// 由於它有一個私有屬性的標識符
複製代碼
ECMAScript私有屬性和普通的私有屬性的異同:
對於第二條舉例,對於普通的屬性在子類種重複申明,父類的中的屬性會被覆蓋。
class C {
foo = 10;
cHelper() {
return this.foo;
}
}
class D extends C {
foo = 20;
dHelper() {
return this.foo;
}
}
let instance = new D();
// 'this.foo' 在每一個實例中都引入了相同的屬性
console.log(instance.cHelper()); // prints '20'
console.log(instance.dHelper()); // prints '20'
複製代碼
使用私有屬性後:
class C {
#foo = 10;
cHelper() {
return this.#foo;
}
}
class D extends C {
#foo = 20;
dHelper() {
return this.#foo;
}
}
let instance = new D();
// 'this.#foo' 對於每一個類都引入了不一樣的屬性
console.log(instance.cHelper()); // prints '10'
console.log(instance.dHelper()); // prints '20'
複製代碼
private關鍵字 VS ECMAScript 私有屬性
之前的await 關鍵字只能出如今async函數內部:
async function main() {
const response = await fetch("...");
const greeting = await response.text();
console.log(greeting);
}
main()
.catch(e => console.error(e))
複製代碼
當咱們但願一開始就引入的時候每每使用當即執行函數去處理
await Promise.resolve(console.log('🎉'));
// → SyntaxError: await is only valid in async function
(async function() {
await Promise.resolve(console.log('🎉'));
// → 🎉
}());
複製代碼
爲了不引入async函數,提供了一個稱爲頂層 await的特性
const response = await fetch("...");
const greeting = await response.text();
console.log(greeting);
// Make sure we're a module
export {};
複製代碼
經過頂層await咱們能夠有如下幾種用法:
const strings = await import(`/i18n/${navigator.language}`); // 動態引入路徑
複製代碼
const connection = await dbConnector(); // 資源初始化
複製代碼
let jQuery; // 依賴回退
try {
jQuery = await import('https://cdn-a.example.com/jQuery');
} catch {
jQuery = await import('https://cdn-b.example.com/jQuery');
}
複製代碼
參考文章: