function f(x: unknown) {switch (true) {case typeof x === "string":// 这里,'x' 是一个 'string'console.log(x.toUpperCase());case Array.isArray(x):// 这里 'x' 是一个 'string | any[]'console.log(x.length);default:// 这里 'x' 是 'unknown'// ...}}布尔值比较有时候你可能会在条件语句中直接与 true 或 false 进行比较 。通常这些比较是不必要的,但可能出于代码风格或避免 JavaScript 真值方面的某些问题而偏好这种写法 。然而,在之前的 TypeScript 版本中,它不能正确地识别这种形式来执行类型缩小 。
【TypeScript 5.3 来了,一大波新特性】TypeScript 5.3 现在在缩小变量范围时可以跟上并理解这些表达式 。
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) {console.log(x.a); // works!}}Symbol.hasInstanceJavaScript 的一个特性是可以重写 instanceof 运算符的行为 。要实现这一点,需要在 instanceof 运算符右侧的值上定义一个名为 Symbol.hasInstance 的特定方法 。
class Weirdo {static [Symbol.hasInstance](testedValue) {return testedValue =https://www.isolves.com/it/cxkf/bk/2023-11-16/== undefined;}}// falseconsole.log(new Thing() instanceof Weirdo);// trueconsole.log(undefined instanceof Weirdo);为了更好地模拟 instanceof 运算符的行为 , TypeScript 现在会检查是否存在 [Symbol.hasInstance] 方法,并且该方法被声明为类型断言函数 。如果存在这样的方法,那么通过 instanceof 运算符对左侧测试的值将会被相应地进行类型缩小 。
interface PointLike {x: number;y: number;}class Point implements PointLike {x: number;y: number;constructor(x: number, y: number) {this.x = x;this.y = y;}distanceFromOrigin() {return Math.sqrt(this.x ** 2 + this.y ** 2);}static [Symbol.hasInstance](val: unknown): val is PointLike {return !!val && typeof val === "object" &&"x" in val && "y" in val &&typeof val.x === "number" &&typeof val.y === "number";}}function f(value: unknown) {if (value instanceof Point) {// 可以访问这两个属性 - 正确!value.x;value.y;// 无法访问这个属性 , 有 'PointLike' 类型的对象,但实际上并没有 'Point' 类型的对象 。value.distanceFromOrigin();}}在这个例子中,Point 定义了自己的 [Symbol.hasInstance]方法 。它实际上充当了一个对称为 PointLike 的独立类型的自定义类型保护程序 。在函数 f 中,我们能够通过 instanceof 将 value 缩小到 PointLike 类型 , 但无法缩小到 Point 类型 。这意味着可以访问属性 x 和 y , 但无法访问 distanceFromOrigin 方法 。
实例字段上的 super 属性访问检查在 JavaScript 中,可以通过 super 关键字访问基类中的声明 。
class Base {someMethod() {console.log("Base method called!");}}class Derived extends Base {someMethod() {console.log("Derived method called!");super.someMethod();}}new Derived().someMethod();// 输出结果://Derived method called!//Base method called!这与编写像 this.someMethod() 这样的代码是不同的,因为那样可能会调用一个被重写的方法,如果一个声明根本没有被重写,那么通常这两种方式是可以互换的 。
class Base {someMethod() {console.log("someMethod called!");}}class Derived extends Base {someOtherMethod() {// These act identically.this.someMethod();super.someMethod();}}new Derived().someOtherMethod();// 输出结果://someMethod called!//someMethod called!问题在于这两种方式是不能互换使用的 , 因为 super 只能用于在原型上声明的成员,而不能用于实例属性 。这意味着如果你写了 super.someMethod() , 但 someMethod 被定义为一个字段,那么就会出现运行时错误!
class Base {someMethod = () => {console.log("someMethod called!");}}class Derived extends Base {someOtherMethod() {super.someMethod();}}new Derived().someOtherMethod();TypeScript 5.3 现在更仔细地检查 super 属性访问/方法调用,以查看它们是否对应于类字段 。如果是的话,现在会得到一个类型检查错误 。
嵌入提示支持跳转到类型的定义TypeScript 的嵌入提示现在支持跳转到类型的定义!

文章插图
按住 Ctrl 键单击嵌入提示可跳转至参数类型的定义 。
推荐阅读
- JDK11 升级 JDK17 最全实践干货来了
- Lisa豪门梦碎后,妆造又黑又丑,参加疯马秀的报应来了?
- 《歌手2024》首发名单曝光,林俊杰终于来了,但夺冠有压力
- “二手市场”成女明星的照妖镜,谁没底线、谁割韭菜,全照出来了
- 王菲现身机场,小腹隆起疑似怀孕,她和谢霆锋终于盼来了这一天
- 梦见孩子回来了是什么意思周公解梦 梦见孩子回来了是什么意思
- 时隔四年,德云社再度举办纲丝节,节目单已经发布,能来的都来了
- 刀郎被迫取消演唱会的真相来了
- “二手平台”成女明星的照妖镜,谁割韭菜,谁没底线,全照出来了
- 11月7日那英定居英国的真相来了
