原文连接 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');
}
复制代码
参考文章: