You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// 旧版本tstypet1=[...string[]]typet2=[...[string,number]]// error: A rest element type must be an array type.typet3=[...string[],string]// A rest element must be last in a tuple type
classSquare{// error: Member 'sideLength' implicitly has an 'any' type.sideLength;constructor(sideLength: number){this.initialize(sideLength)}initialize(sideLength: number){this.sideLength=sideLength;}}
"use strict";exports.__esModule=true;/** @jsx h *//** @jsxFrag Fragment */varpreact_1=require("preact");varstuff=preact_1.h(preact_1.Fragment,null,preact_1.h("div",null,"Hello"));
classBase{getfoo(){return100;}setfoo(val){// ... }}classDerivedextendsBase{// 旧版本在使用useDefineForClassFields选项会报错 error: 'foo' is defined as an accessor in class 'Base', but is overridden here in 'Derived' as an instance property.foo=10;}
interfaceThing{prop: string;a: unknown;b: any;c: never;d: undefined;}functionf(x: Thing){deletex.prop;// error: The operand of a 'delete' operator must be optional.deletex.adeletex.bdeletex.cdeletex.d}
可变元组类型(Variadic Tuple Types)
旧版本
Typescript
要实现一个concat
方法,一般实现方式是:这种方式实现的
concat
方法的返回值类型是一个联合类型的数组(T | U)[]
如果要对元祖进行concat操作呢
元祖具有特定长度和元素类型,上例的返回值类型显然是不精确的,期望的返回值类型是
[number, string, boolean]
要实现期望的结果,在旧版本的TS中只能编写重载
但如果传入的元祖长度不能确定,我们只能不断的编写重载以尽可能覆盖所有的情况,这显然是不可接受的。
TypeScript 4.0 带来了两个基础更改,并在推断方面进行了改进,从而可以类型化这些内容。
其中一个更改是范型可用于扩展运算符。这意味着可以用范型声明一个可变的元祖。
由此就可以实现一个类型支持更好的
concat
函数另一个更改是旧版本Typescript的
rest
参数只支持数组类型,且必须放在元祖的最后;而现在可以放在元祖的任意位置。不确定长度的数组类型使用扩展运算符,如果不放置于最后,那其后的所有元素都将被推断该数组元素的类型和其后元素类型的联合类型
标记元祖元素(Labeled Tuple Elements)
如果我们要创建一个图标,可能有如下实现
其中的size参数是元祖类型,但我们在调用
createIcon
方法的时候只清楚size
的类型,并不清楚每个元素的意义。在调用时还需要跳转到函数体去查看size每个元素的意义。在Typescript 4.0中,元祖元素可以被标记。上例中的
createIcon
方法可以这样实现:这样在调用时就能查看
size
参数每个元素的意义一些使用规则
在标记一个元组元素时,还必须标记元组中的所有其他元素。
解构标记时无需使用不同名称命名变量。如下例,解构
size
参数时变量命名无需使用width
和height
使用带标记的元祖可实现重载
从构造器函数中推断类属性(Class Property Inference from Constructors)
如下例,在旧版本的
Typescript
中,当开启了noImplicitAny
选项,定义的实例属性area
和sideLength
会报错。因为其没有显式声明类型,从而被推断为any。而在Typescript 4.0中该实例属性的类型会从
constructor
函数中推断,area
和sideLength
都被推断为number类型,不会报错。如果对类实例属性的初始化没有写在
constructor
函数中,Typescript
就无法推断该实例属性的类型。此时需要显示声明实例属性的类型,而如果开启
strictPropertyInitialization
选项(检查已声明但未在构造函数中设置的类属性)还需要显示赋值断言来使类型系统识别类型短路赋值运算符(Short-Circuiting Assignment Operators)
ES2021新增的特性中包含了逻辑赋值运算符(Logical Assignment Operators)的提案。
当变量a为truthy时,将其值设置为b,即等价于
a = a && b
当变量a为falsy时,将其设置为b,即等价于
a = a || b
当变量a为nullish时,将其设置为b,即等价于
a = a ?? b
。??
操作符是ES2020的新增特性Nullish CoalescingTypescript 4.0支持了上述特性
catch子句变量支持声明为unknown(unknown on catch Clause Bindings)
在旧版本的Typescript中,catch子句的变量拥有
any
类型,且不可以被声明为其他类型在Typescript 4.0版本支持将该变量声明为
unknown
,上例不会报错。之所以这样做是因为
any
类型可以兼容其他所有类型,如上例对err
变量进行任何操作都不会报类型错误。而unknown
比any
更安全,因为它会在我们操作值之前提醒我们执行某种类型检查。定制 JSX Fragment 工厂函数
旧版本的Typescript便已支持定制
JSX
工厂函数,可通过jsxFactory
选项进行定制。在Typescript 4.0中支持通过新的
jsxFragmentFactory
选项来定制Fragment
工厂函数。如下
tsconfig.json
配置告诉TypeScript
以与React
兼容的方式转换JSX
,但将每个工厂函数切换为h
而不是React.createElement
,并使用Fragment
而不是React.Fragment
。使用如下
tsconfig.json
配置编译如下代码
将输出
JSX
工厂函数支持使用/** @jsx */
注释,去指定当前文件使用的JSX
工厂函数。同样,Fragment
工厂函数可通过新的/** @jsxFrag */
注释去指定。如下,在文件头部指定当前文件使用的
JSX
工厂函数和Fragment
工厂函数。通过注释指定的方式比在
tsconfig.json
文件中配置的优先级高重大更改
lib.d.ts
Typescript 4.0删除了
document.origin
,它仅在 IE 的旧版本中有效,而 Safari MDN 建议改用 self.origin。如下,在Typescript 4.0版本访问
document
的origin
属性将提示该属性不存在如果要在旧版本的IE使用该属性,需要显式设置
属性重写访问器(反之亦然)会报错(Properties Overriding Accessors (and vice versa) is an Error)
旧版本的Typescript中,子类的实例属性覆盖父类的访问器属性只有在使用
useDefineForClassFields
选项时才会报错。而在Typescript 4.0版本中,无论是否使用
useDefineForClassFields
选项,子类的实例属性覆盖父类的访问器属性(或子类的访问器属性覆盖父类的实例属性)总是报错。delete 的操作对象必须是可选的
Typescript 4.0版本在启用
strictNullChecks
选项时,使用delete
运算符,操作对象现在必须为any
、unknown
、never
或为可选(因为它在类型中包含undefined
)。否则,使用delete
运算符将会报错。参考资料
The text was updated successfully, but these errors were encountered: