TypeScript 4.3 新增 feature

2,866 阅读2分钟

本系列作为《TypeScript 入门实战笔记》课程(见拉勾教育)的补丁,随时更新。

类相关

override

添加 override 修饰符,实现更智能的方法重写检测。如以下示例所示:通过 override 重写基类不存在的方法 bak,提示 ts(4113) 错误;但重写 getName 方法则 ok。这个特性可以保证,我们在重构基类的时候,相应可以检测出需要同步修改的子类方法。

class Animal {
  getName() { return ''; }
}
class Dog extends Animal {
  override bak() { // ts(4113)
    return 'wang';
  }
  override getName() { // ok
    return 'wang';
  }
}

get & set 类型

允许 get 和 set 支持不同的类型,援引官方说明。

class Thing {
    #size = 0;

    get size(): number {
        return this.#size;
    }

    set size(value: string | number | boolean) {
        let num = Number(value);

        // Don't allow NaN and stuff.
        if (!Number.isFinite(num)) {
            this.#size = 0;
            return;
        }

        this.#size = num;
    }
}

静态索引签名

略,援引官方说明。

class Foo {
    hello = "hello";
    static world = 1234;
    
    // 索引签名:
    [propName: string]: string | number | undefined;
    // 静态索引签名
    static [propName: string]: string | number | undefined;
}

let instance = new Foo();

// ok
instance["whatever"] = 42;
// ok
Foo["whatever"] = 42;

泛型相关

Contextual Narrowing for Generics(泛型上下文缩小)

课程第 11 讲里提到了“失效的类型守卫”,如以下示例注释 C3 描述的地方。

在 4.2.* 以前的版本 pet 的类型并不会缩小(type narrowing)成 Cat 的子类型(P & Cat),我们需要 (pet as Cat).miao 类型断言来避免提示 ts(2339) 错误。

在 4.3.2 版本里,针对泛型添加了上下文(类型)缩小,即在不破坏类型约束的情况下、根据上下文缩小泛型类型,表现为:

  • 如注释 C1 所示,pet.bak 操作里 pet 的类型缩小为 Dog;但如注释 C2 所示,pet 的类型依旧是 P & Dog;
  • 如注释 C3 所以,pet.miao 操作里 pet 类型缩小为 Cat;但是如注释 C4 所示,pet 的类型依旧是 P;
class Animal {
  name: string = 'Animal';
}
class Dog extends Animal {
  bak() { return 'wang';}
}
class Cat extends Animal {
  miao() {return 'miao';}
}

function MyPet<P extends Dog | Cat>(pet: P): P {
  if (pet instanceof Dog) {
    // C1
    pet.bak;
    // C2
    return pet;
  }
  // C3
  // ok: 4.3.2 上下文缩小,可以被当做 Cat 对待;
  // error: 4.2.* 及以下,提示 ts 2339 错误;
  pet.miao;
  // C4
  return pet;
}

模板字符串类型相关

支持匹配模式、排列组合等智能类型,援引官方示例:

type Color = "red" | "blue";
type Quantity = "one" | "two";

type SeussFish = `${Quantity | Color} fish`;
// same as
//   type SeussFish = "one fish" | "two fish"
//                  | "red fish" | "blue fish";

declare let s1: `${number}-${number}-${number}`;
declare let s2: `1-2-3`;

// ok
s1 = s2;

附录