前言
学习ts是去年小程序项目里第一次尝试使用,公司的领导们经过商量讨论觉得有必要去使用ts在开发中,正好新开了一个小程序的项目,使用MPX进行搭建,以前没有接触过ts看官方文档,被那么多
特性吓尿了,但是实际上写业务用的特性不多。开发过程也遇到了一些问题,本篇就算是记录总结问题,查漏补缺,加深记忆,后期遇到问题也会不定时更新,大家有什么问题也可以留言,统一进行整理补充,共同进步✌🏻
理论知识这种东西,学了还是要总结,梳理清楚自己对当前知识的掌握程度。帮助自己进行短板补缺,记录分享,也是一件很有意思的事。
问题
下边就是ts常见的一些问题的汇总,方便自己查阅,也帮助其他遇到问题的小伙伴有一个快速解决的途径,进行整理。
1.什么时候用any?什么时候用unkown?有没有规律或准则?
从字面理解可以这么区分:
any 的意思是,程序员认为 aaa 可以是任何类型(动态的),所以 aaa.xxx 中不管 xxx 是什么,都能通过语法检查,毕竟它是动态的,有的时候有 .xxx 有的时候没有 .xxx 都是可能的。
unknown 的意思是,程序员目前不知道 uuu 的类型(未知的),所以一般需要在用之前断言一下,才能通过语法检查。断言错了咋办?如上面的例子就断言错误,那就是断言者自己的问题了。
使用的具体规则
如果一个变量的类型是变化的(比如来自 JS 程序的对象,随时都有可能多一个属性,甚至变成完全不同的类型),就用 any。
如果一个变量的类型是固定的,但是目前还不能确定或不想确定,就用 unknown。要用这个变量的时候就断言一下吧,不能像 any 那样糊里糊涂地用。
我个人的经验是能用 unknown 就尽量用 unknown,不要滥用 any。大量的使用any其实在开发中一点帮助没有,反而会增加一些工作量。
2.null和 undefined 给其他类型的赋值问题
null
和 undefined
是其他类型的子类型,可以赋值给其他类型,比如可以赋值给number
类型,赋值后的变量由number
类型转换为undefined
类型。如下图:
在
strictNullChecks
严格空检查模式下,null
和 undefined
不能赋值给其他类型变量。
3.never和void的区别
void
可以被赋值为null
和undefined
类型。never
返回一个不包含值的类型。
拥有void
作为返回值类型的函数可以正常运行。拥有never返回值类型的函数 无法正常返回, 无法终止,或抛出异常。
strictNullChecks
模式下,上方foo3
代码将不会被执行,x
无法被观察.
4.number和BigInt不是一个类型,不可以兼容互相赋值
5.字面量类型和类型字面量
字面量类型
在 TypeScript 中,字面量不仅可以表示值,还可以表示类型,即所谓的字面量类型。
目前,TypeScript 支持 3 种字面量类型:字符串字面量类型、数字字面量类型、布尔字面量类型,对应的字符串字面量、数字字面量、布尔字面量分别拥有与其值一样的字面量类型,字面量类型是集合类型的子类型,它是集合类型的一种更具体的表达。比如 'UP' (这里表示一个字符串字面量类型)类型是 string 类型(确切地说是 string 类型的子类型),而 string 类型不一定是 'UP'(这里表示一个字符串字面量类型)类型。
一般来说,我们可以使用一个字符串字面量类型作为变量的类型,如下代码所示:
定义类型后可以进行组合使用,校验时如果选择的是非定义时的类型就会报错
字面量类型拓宽
所有通过 let 或 var 定义的变量、函数的形参、对象的非只读属性,如果满足指定了初始值且未显式添加类型注解的条件,那么它们推断出来的类型就是指定的初始值字面量类型拓宽后的类型,这就是字面量类型拓宽。
下面我们通过字符串字面量的示例来理解一下字面量类型拓宽:
因为string和stringFunc满足了 let、形参且未显式声明类型注解的条件,所以变量、形参的类型拓宽为 string(形参类型确切地讲是 string | undefined)。
因为specifiedStr的常量不可变更,类型没有拓宽,所以 specifiedStr 的类型是 'it is a string' 字面量类型。
因为strNew赋予的值 specifiedStr 的类型是字面量类型,且没有显式类型注解,所以变量、形参的类型也被拓宽了。其实,这样的设计符合实际编程诉求。我们设想一下,如果 strNew 的类型被推断为 'this is string',它将不可变更,因为赋予任何其他的字符串类型的值都会提示类型错误。
类型字面量
可以通过添加?的方式来进行参数选填的操作,使用时也不会有报错问题出现。
6.类里面的修饰符public private protected区别
第一个报错
this.age
,age
通过private
定义,所以只有在类里乐意访问,子类和实例化后都不能访问。
第二个报错同理,第三个报错属性通过
protected
定义,所以类中,子类可以访问,实例化以后不支持访问。