【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 私有字段有一些规则

  1. 私有字段使用 # 字符作为开始

  2. 每个私有字段的名称,在被包含的类中是唯一的

  3. TS 中,public 和 private 修饰符不能用于私有字段

  4. 私有字段不能在包含类之外访问

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/

个人博客:http://www.pingan8787.com 微信公众号【前端自习课】和千万网友一起,每日清晨,享受一篇前端优秀文章。 目前已连续推送文章 600+ 天,愿每个人的初心都能一直坚持下去!
原文地址:https://www.cnblogs.com/pingan8787/p/13069381.html