【TS】588- TypeScript 3.8 新增特性介绍
近期 typescript 发布 3.8版本,增加了部分新特性,下文主要围绕几个主要特性做一些介绍。
Type-Only Imports and Export
TS 中重用了 JS 的导入语法,在我们日常使用 TS 导入功能时因为 import elision 特性,我们不必担心我们导入了什么,把我们想导入的东西全导入即可,导入方式无差别,只是在 TS 转 JS 的时候,TS 会识别出那些导入项被当做类型使用,它将其删除。这看起来不错,但是在某些场景下会产生一些问题。
第一种情况:
import { MyThing } from "./some-module.js";
export { MyThing };
上述代码只看的话我们是不知道 MyThing 是一个类型还是一个值,如果他是一个类型的话,那么 TS 使用的 transpileModule API 编译出的代码将无法使用,isolatedModules 也会提醒我们无法这样使用。
第二种情况:
// ./service.ts
export class Service {
// ...
}
register("globalServiceId", Service);
// ./consumer.ts
import { Service } from "./service.js";
inject("globalServiceId", function (service: Service) {
// do stuff with Service
});
上述代码出现在 Angular.js (1.x) 中,service 需要在全局注册,但是导入的 service 仅仅用于类型声明,因为上面提到的 import elision 特性,导致 service.js 中的代码不会被执行,导致运行错误。
以上为两个比较典型的问题,究其原因最终是,TS没有提供一种方式能识别它到底是不是一个类型。为了解决这个问题,TS3.8版本中添加了一个 Type-Only Imports and Export 来解决这个问题,具体使用方式如下
import type { SomeThing } from "./some-module.js";
export type { SomeThing };
import type 被用作类型注释或声明的声明语句,总是会在 TS 转 JS 中被完全删除,不会出现在JS代码中,export type 仅提供一个用于类型的导出,同样也会被删除。通过这种方式,可以有效的解决上述两个问题。
pr地址
https://github.com/microsoft/TypeScript/pull/35200
ECMAScript Private Fields
TS3.8 支持了在 ECMAScript 处于 stage-3 中的私有字段。
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
// ~~~~~
// Property '#name' is not accessible outside class 'Person'
// because it has a private identifier.
typescript 私有字段有一些规则
私有字段使用 # 字符作为开始
每个私有字段的名称,在被包含的类中是唯一的
TS 中,public 和 private 修饰符不能用于私有字段
私有字段不能在包含类之外访问
pr地址
https://github.com/Microsoft/TypeScript/pull/30829
Top-Level await
一个经常遇到的问题,await 只能在 async 函数中使用,但是对于顶层调用我们必须再包一个冗余的 async 函数,来实现从顶层使用 await 的目的。ts3.8 支持了 Top-Level await 让我们可以省去这部分包装代码。
const response = await fetch("...");
const greeting = await response.text();
console.log(greeting);
// Make sure we're a module
export {};
此外注意一点,Top-Level await 只在顶级模块工作,所以代码中需要含有 export 或者 import 才会认为该文件是一个模块。对于没有依赖的情况下,可以使用 export {}
pr地址
https://github.com/microsoft/TypeScript/pull/35813
JSDoc Property Modifiers
TS3.8 通过打开 allJs 选项,能支持JS文件,并且当使用 checkJs 或者在你的.js文件顶部添加 // @ts-check 注释时,TS能对这些JS文件进行类型检查。
// @ts-check
class Foo {
constructor() {
/** @private */
this.stuff = 100;
}
printStuff() {
console.log(this.stuff);
}
}
new Foo().stuff;
// ~~~~~
// error! Property 'stuff' is private and only accessible within class 'Foo'.
TS 选用 JSDoc 进行语法类型检查,而TS3.8能理解一些新的 JSDoc 属性标签。比如所有的访问修饰符 @public、@private、@protected,使用方式和 TS 中使用方式相同。
export * as ns Syntax
以前我们只能这样使用
import * as utilities from "./utilities.js";
export { utilities };
TS3.8 支持了下述用法
export * as utilities from "./utilities.js";
其他
本文介绍了几个比较重要的特性,更多新增特性可查看下述链接
文章
https://devblogs.microsoft.com/typescript/announcing-typescript-3-8/
END
了解更多
点击下方图片即可阅读