2023.11.29前端周刊

51 阅读2分钟

本专栏(FE weekly news)文章随缘更新,由于精力有限,每篇周报的内容可能不多,欢迎大家关注

1. State of JavaScript 2023

一年一度的State of JavaScript调查开始了,感兴趣的可以参与填写调查问卷。

2. Announcing TypeScript 5.3

TypeScript5.3发布了,更新了如下内容:

  1. Import Attributes:允许用户手动声明所import模块的类型。防止我们的模块被解释为自己预期外的类型。

    // 告诉解释器我们引入的是一个json文件,而非有.json后缀的js文件
    import obj from "./something.json" with { type: "json" };
    

    注意:这个type我们可以随便指定,ts不会设限,但在浏览器里能不能运行就另说了

    比如下面这段代码,ts也不会报错

    import * as foo from "./foo.js" with { type: "fluffy bunny" };
    
  2. 稳定支持类型导入中的resolution-mode,从而自由使用CommonJS/ES Module模块中的类型

    // Resolve `pkg` as if we were importing with a `require()` 
    import type { TypeFromRequire } from "pkg" with { "resolution-mode": "require" }; 
    // Resolve `pkg` as if we were importing with an `import` 
    import type { TypeFromImport } from "pkg" with { "resolution-mode": "import" }; 
    export interface MergedType extends TypeFromRequire, TypeFromImport {}
    
  3. 实现了switch(true)时各条件分支下的类型收紧。

    function f(x: unknown) {
      switch (true) {
        case typeof x === "string": 
          // 在5.3之后,x将成功收紧为string类型,5.3之前则不会收紧(仍然为unknow)
          console.log(x.toUpperCase());
        case Array.isArray(x): 
          // x收紧为string | any[]类型 
          console.log(x.length); 
        default: 
          // x为unknown类型
      }
    }
    
  4. 实现了布尔判断后的类型收紧

    interface A { a: string }
    interface B { b: string }
    type MyType = A | B; 
    
    function isA(x: MyType): x is A {
      return "a" in x; 
    }
    function someFn(x: MyType) {
      if (isA(x) === true) {
        // 5.3后x将成功收紧为A类型
        console.log(x.a);
      }
    }
    
  5. 通过Symbol.hasInstance实现instanceof判断后的类型收紧

    注:通过Symbol.hasInstance可以定义instanceof的判定条件。

    interface PointLike {
       // ....
    }
    
    class Point implements PointLike {
        static [Symbol.hasInstance](testedValue): testedValue is PointLike {
           // ...
        }
    }
    
    function f(value: unknown) {
        if(value instanceof Point) {
            // 经过这层判断,ts5.3会将value收紧为PointLike类型
        }
    }
    
    
  6. 对于super调用时的类型校验更加细化

    class Base1 {
        someMethod() {
          console.log("Base1 someMethod called!");
        }
    }
    class Base2 {
        someMethod = () => {
            console.log("someMethod called!");
        }
    }
    class Derived1 extends Base1 {
        someOtherMethod() {
            super.someMethod();
        }
    }
    class Derived2 extends Base2 {
        someOtherMethod() {
            super.someMethod();
        }
    }
    // 校验通过
    new Derived1().someOtherMethod(); // Base1 someMethod called!
    // 此处校验将不通过(因为someMethod并不是挂载在prototype上,而是挂载在实例上)
    new Derived2().someOtherMethod();
    
  7. 优化了针对JSDoc的解析策略,以后JSDoc默认不再被解析,从而提高了项目的编译速度

  8. 优化了交集的判断逻辑

    在5.3之前,判断A&(B|C)时会先转换为(A&B)|(A&C)。这样会导致极大的浪费,比如:

    判断SomeType & (Type1 | Type2 | ... | Type99999NINE)时,需要实际判断的表达式为(SomeType & Type1) | (SomeType & Type2) | ... |(SomeType & Type99999NINE),这样我们需要进行99999次当前类型是否为SomeType的判断。

    5.3之后ts会先判断是否为SomeType类型,再判断是否为后面的并集类型