关于TypeScript 5.3 Beta的最新更新的二三事
聊聊TypeScript 5.3 Beta更新内容
- 导入属性
- 稳定支持导入类型
resolution-mode
switch (true)
缩小- 缩小与布尔值的比较范围
instanceof
缩小范围Symbol.hasInstance
- 检查实例字段的属性访问
super
还有一些性能上的优化和开发体验的优化。ok下面我们就详细的讲一下这些更新都做了一些什么事情,日常有什么使用场景。
导入属性和稳定支持导入类型resolution-mode
想深入了解一下这个我们需要先看懂关于导入带有断言的 ES 模块的语法建议这个提案中的JSON模块这个建议,里面说了一种情况。
这个具体解释就是服务器错误地将某个文件的MIME类型标记为
application/javascript
,而实际上这个文件是一个JSON文件,那么当你尝试导入这个文件时,浏览器可能会尝试执行它,因为它认为这是一个JavaScript文件。如果这个JSON文件包含了可执行的JavaScript代码,那么这段代码就会被执行,这可能会导致安全问题。通过使用导入断言,你可以明确地告诉浏览器,你期望这个模块是一个JSON文件,而不是一个JavaScript文件。这样,即使服务器错误地将这个文件的MIME类型标记为application/javascript
,浏览器也不会尝试执行它,因为你已经明确地指定了它应该是一个JSON文件。
但是这个在日常开发中是很难碰到的。
ok理解了为什么有的导入需要断言之后我们再回头来看TypeScript 5.3 Beta更新的导入属性的语法就不难理解了。
import obj from "./something.json" with { type: "json" };
const obj = await import("./something.json", { with: { type: "json" } });
当然导入语法不止这些,在es的提案中说到了可以断言其他的类型。
但是目前还没有实装。
稳定支持导入类型resolution-mode
,就是对仅类型导入的断言。
import type { TypeFromRequire } from "pkg" with { "resolution-mode": "require" };
import type { TypeFromImport } from "pkg" with { "resolution-mode": "import" };
export interface MergedType extends TypeFromRequire, TypeFromImport {}
switch (true)
缩小和缩小与布尔值的比较范围
这两条我认为可以一起来讲这两条理解也比较容易直接上案例。
function f(x: unknown) {
switch (true) {
case typeof x === "string":
// 'x' is a 'string' here
console.log(x.toUpperCase());
// falls through...
case Array.isArray(x):
// 'x' is a 'string | any[]' here.
console.log(x.length);
// falls through...
default:
// 'x' is 'unknown' here.
// ...
}
}
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!
}
}
这里我直接拿官网的案例过来了,先看switch语法在5.3之前就算你用switch case去判断这个变量的类型之后他的类型并没有像预期一样收窄。这件事是有点反直觉的在5.3版本ts修复了这个问题。再看if的案例,就会发现其实他们是同一类问题都在这个版本的到了修复,此pr。
instanceof
缩小范围Symbol.hasInstance
聊这个更新之前我们要先去了解一下什么是Symbol.hasInstanc
,这个在mdn中是有定义的他是用来处理判断某对象是否为某构造器的实例。因此你可以用它自定义 instanceof
操作符在某个类上的行为。ok了解这个定义之后我们再来看一下ts5.3给的官方案例。
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) {
// Can access both of these - correct!
value.x;
value.y;
// Can't access this - we have a 'PointLike',
// but we don't *actually* have a 'Point'.
value.distanceFromOrigin();
}
}
其实不难发现,他最终的目的与收窄布尔值的作用类似,他可以通过instanceof去定义一个变量的类型。
总结
在整个TypeScript 5.3 Beta版本的更新中,我感觉与开发体验相关的内容也是一次不错的更新,其中修复了让人恼怒的布尔值判读之后类型无法收缩的问题。
转载自:https://juejin.cn/post/7290734076583346191