40句话总结TypeScript

135 阅读8分钟

1.JavaScript作为弱类型语言,错误只有在运行时才会暴露,这是ts出现的原因

2.TypeScript = type + JavaScript

3.ts编译就是使用类型检查器对js或者ts代码进行类型检查并且报告问题,最终输出js代码

4.ts可以通过强制类型安全提升js代码的健壮性,但是提升不了js代码的其他水平

5.ts转换js需要时间,但是对于性能的影响很小,而类型分析和ts转换js的语法分析是单独完成的,不会与生成可运行应用程序代码文件混在一起,所以ts对于性能的影响微乎其微

6.ts类型系统运作方式:将代码中所有可能出现的值(通过类型推断得到,如果变量没有初始值,则无法进行类型推断,就需要类型注解推断出变量值允许的类型,如果既没有类型推断,也没有类型注解,默认类型any,any类型变量可以赋任何类型的值)和他们将被使用的方式作比对(类型判断),如果不匹配则反馈类型错误

7.类型就是值的形状

8.字面量类型(已知为原始类型的特定值的值的类型)是原始类型的更具体版本

9.联合类型(后续一般需要缩小类型)用于处理可能是两种或者多种潜在类型的值,而字面量类型恰恰相反,字面量类型是原始类型的更具体版本

10.缩小类型就是对值的范围进一步缩小(推断)

11.管道运算符 |

12.类型别名 type

13.变量赋值给变量不会触发类型推断( 将对象变量赋值给声明了对象字面量类型的变量不会触发类型推断( type obj = {a:number} const obj1 = {a:1,b:2} const obj:obj = obj1//正常编译 ),如果将对象字面量直接赋值给变量,会进行类型推断( type obj = {a:number} )

14.ts的类型系统工作起始于类型推断/类型注解获取变量的类型(或者说,获取变量的所有可能的值,再或者说获取值的形状。类型包括原始类型和字面量类型,如果值的形状相对于原始类型需要进一步确定,使用字面量类型检查(对象一般使用字面量类型检查);如果值的形状可能满足多种类型,用联合类型检查(后续如果值的形状需要进一步确定,进行类型缩小)或者交叉类型(原始类型不能交叉)),从而与变量所有的使用情况做比对,确定类型是否匹配。

15.类型检查对于所有类型都要有效,对于对象,同样可以进行类型推断/类型注解,ts的类型检查器可以进行结构化类型检查,检查对象的属性是否满足类型要求,并且可以检查嵌套的对象属性。

16.js函数四种参数类型:

1>具体传参:

必传:必传参数

可传可不传:可选参数(?) 默认参数

2>模糊传参:剩余参数(...args:string[])

17.ts拒绝尝试推断递归函数的返回类型,只能用类型注解(函数返回值注解在参数列表小括号右面)

18.void类型的返回值表示函数不返回值,never表示永不 返回(throw error或者无限循环的函数)

19.函数字面量类型使用时候注意加功能类型括号(小括号),可读性更好的函数重载写法

20.多维数组类型是字面量类型的应用,例:let arr : number[][] === let arr :(number[])[]

21.ts类型系统的不足:

1> ts假设所有数组成员的访问都会返回该数组的一个成员,不论索引是否大于数组长度(ts的存在就是为了让代码在编译期间尽可能的暴露错误,让代码在运行期间不会报错,索引大于数组长度的数组成员访问很明显会给运行期埋下报错的可能)

2> 对象索引签名不能检查成员值的形状,认为所有的索引签名都能返回索引签名的类型,无论他定义与否。

22.对象类型是结构化类型,数组类型则是数组元素类型

23.元组类型,是比数组字面量类型还要具体的数组类型,所以字面量类型也不能赋值给元组类型,数组类型推断会优先推断数组原始类型,使用as const断言可以推断为元组类型

24.接口(implements interface)描述对象类型的好处:可以继承(extends),还可以合并接口,后定义的接口的成员如果与先定义的同名接口的同名属性类型不同会报错,接口方法可以重载,但是接口的函数属性不可以

25.类函数两种写法区别:类方法会挂载到类原型上,所有实例共用一个函数定义,类属性则对于每个实例都是全新的函数

26.要从类中读取或写入属性,必须在类中明确声明该属性。并且类属性必须分配一个值(无论是constructor赋值还是类属性直接赋值,避免类实例读取undefined)

27.!禁用初始化检查,一般需要禁用初始化检查意味着代码的设置方式不适合类型检查,与其通过断言降低属性类型安全性,不如考虑重构类,使其不需要断言禁用初始化检查

  1. readonly和const都会导致类型推断不会推断原始类型,而是推断成为字面量类型,因为他们都知道这个变量不会改变了

29.类在类型系统中相对独特,因为类声明既创建了运行时值(类本身),也创建了可用于类型注释的类型。

30.类可以实现接口,但接口不会改变类,类必须满足他匹配的所有接口,接口会检查类的成员,但不会改变类的成员

31.继承extends是扩展,必须保证子类能满足基类类的类型要求,重载基类构造函数,必须在访问this或者super之前调用基类构造函数super(),重载基类方法,必须保证参数与返回值不与基类同名方法冲突,属性同样,总之牢记extends的原则,是扩展,不是改变!保证子类实例可以当作基类实例使用是最大的前提!

32.接口相对于对象类型的好处是可以合并可以继承,而类对比接口,类不仅是类型,更是运行时同样存在的类, 类同样可以继承(extends是扩展,基类不会改变,扩展的原则是子类实例可以当作基类实例使用,即子类必须满足基类类型要求),但是不可以合并,不过类可以implements实现多个接口(接口对类有类型要求,但是接口不会改变类),类的所有成员并不是都可以随意访问的,抽象类的abstract修饰的成员必须有实例才可以访问,而static修饰的静态成员,不需要实例化,可以直接通过类名访问,不能直接以类名访问,protected修饰的成员必须是基类/子类中才可以访问,实例也不可以访问,private只能基类中访问,public修饰的成员则是谁都可以访问

33.底部类型就是不能到达的类型,顶部类型就是都能到达的类型,ts顶部类型有any和unknown,unknown不能赋值给非顶部类型,且不能访问unknown的属性

34.对于返回值是布尔值的函数,添加类型谓词(参数 :参数 is nrrowType) 可以针对返回值为true或者false的时候对参数做相应的类型缩小

35.keyof,它接受一个现有类型并返回允许在该类型上的所有键的联合,将其放在类型的名称前面,无论何时使用类型注释都可以使用它

36.类型运算符:keyof+typeof,注意ts的typeof 与js运行时typeof不是一个东西

37.any类型与as断言都会让ts类型系统形同虚设,尽量避免使用,as断言分为类型断言(as ['a','b'])和常量断言 as const,前面说的!初始化检查其实是非空断言的简写,全写就是as 除了null/undefined之外的其他类型

38.类型不定,但类型关系已知的情况,使用类型参数来使类、函数、接口实现泛型

39.ts不会推断基类类型参数,没有默认值的类型参数(有默认值的类型参数必须放置到没有默认值的类型参数之后)必须类型注释

40.类的静态成员无法访问类的类型参数