TypeScript 4.6 正式发布了!
如果想要使用TypeScript,可以通过NuGet下载,也可以使用npm命令来下载:npm install typescript
TypeScript 4.6的功能更新:
- 支持
super()前执行构造函数代码
--target es2022
自测试版和RC版以来有什么新功能?
TypeScript 4.6测试版本以来,有两个比较大的功能改进,分别是面向 Destructured Discriminated Unions(可辨识联合类型)控制流分析和--target es2022
,同时另一个值得注意的变化是在react-jsx 模式下删除了void 0 参数。
自RC版本发布之后,TypeScript 团队内部也做了重构,修复了一些问题,纠正了一些奇怪的错误信息,并将部分情况下的类型检查性能提高了3%。
支持super()
前执行构造函数代码
在JavaScript类中,引用super()
之前,必须先调用this
。TypeScript也执行了这一点。在TypeScript中,如果一个构造函数的包含类有任何属性初始化器,那么在构造函数的开头包含任何代码都是错误的。
class Base {
// ...
}
class Derived extends Base {
someProperty = true;
constructor() {
// error!
// have to call 'super()' first because it needs to initialize 'someProperty'.
doSomeStuff();
super();
}
}
而现在 TypeScript 4.6在检查方面变得更加宽松,允许其他代码在super()
...之前运行。
面向 Destructured Discriminated Unions(可辨识联合类型)控制流分析
TypeScript能够根据判别属性来缩小类型。例如,在下面的代码片段中,TypeScript能够通过检查kind
值来缩小action
的类型。
type Action =
| { kind: NumberContents , payload: number }
| { kind: StringContents , payload: string };
function processAction(action: Action) {
if (action.kind === NumberContents ) {
// `action.payload` is a number here.
let num = action.payload * 2
// ...
}
else if (action.kind === StringContents ) {
// `action.payload` is a string here.
const str = action.payload.trim();
// ...
}
}
这一特性使得持有不同数据的对象可以一起工作,不过需要制定一个共同字段来描述这些对象存在哪些数据。
如果想要取消上述例子中的kind
和payload
,可以如下操作。
type Action =
| { kind: NumberContents , payload: number }
| { kind: StringContents , payload: string };
function processAction(action: Action) {
const { kind, payload } = action;
if (kind === NumberContents ) {
let num = payload * 2
// ...
}
else if (kind === StringContents ) {
const str = payload.trim();
// ...
}
}
索引访问推理的改进
TypeScript现在可以正确地推断出索引访问类型,立即索引到一个映射的对象类型。
interface TypeMap {
number : number;
string : string;
boolean : boolean;
}
type UnionRecord<P extends keyof TypeMap> = { [K in P]:
{
kind: K;
v: TypeMap[K];
f: (p: TypeMap[K]) => void;
}
}[P];
function processRecord<K extends keyof TypeMap>(record: UnionRecord<K>) {
record.f(record.v);
}
// This call used to have issues - now works!
processRecord({
kind: string ,
v: hello! ,
// 'val' used to implicitly have the type 'string | number | boolean',
// but now is correctly inferred to just 'string'.
f: val => {
console.log(val.toUpperCase());
}
})
--target es2022
TypeScript 现在支持 --target es2022
。这意味着像类字段 (class fields) 这样的特性现在会有一个可以保留的稳定输出 target,也意味着新的内置功能可以使用新的--target
设置,或者使用--lib es2022
。
删除了react-jsx 中不必要的参数
以前,编译如下代码时--jsx react-jsx
export const el =
foo
;
现在,TypeScript 将生成以下 JavaScript 代码:
import { jsx as _jsx } from react/jsx-runtime ;
export const el = _jsx( div , { children: foo }, void 0);
在这种模式下,最后一个参数void 0
是不必要的,删除它可以提高包的大小。
- export const el = _jsx( div , { children: foo }, void 0);
+ export const el = _jsx( div , { children: foo });