类型声明
类型是小写,比如string、object等,首字母大写是内部类,比如String,new Object
变量声明
变量的类型推导(推断)
=====================
基本类型(数值、布尔、文本)
类型 | 例子 | 说明 |
---|---|---|
number | 1,-1 , 1.5; 0b110 二进制; 0o555 八进制; 0xfff 十六进制; |
数值类型,不区分整数类型(int)和浮点型(double),统一为number类型 |
boolean | true; false; |
布尔类型,true和false,非常简单 |
string | “a”, ‘b’, abc${123} |
文本类型,单引号或者双引号,也支持ES6的模板字符串 |
=====================
“所有” 类型
any 所有类型
想把代码慢慢过渡TS,也可以先使用any类型,后面慢慢改。
但是any 终究是不安全的,因为可以随意变更,关掉了类型检测,就像写JS一样。
也可以在tsconfig.json里面配置能不能使用any。
unknown 安全类型
是ts3.x新增的类型
unknown 类型只能赋值给any或者unknown 类型,防止你拿到别的地方乱用。
除非在使用前对 unknown 类型的值执行大多数操作之前进行某种形式的检查(就是使用typeof 或 instanceof 来判断类型)
=====================
数组类型
Array 数组
统一整个数组的元素,都是同一个类型
第一种写法不推荐,因为很多语言里面都有这样的写法,很容易冲突
对象数组,一般会用一个类表示对象
Tuple 元组
说明
数组的一种,只是可以单独设定每个元素的类型,固定后就没办法变更了。
后面的元祖元素个数不能多也不能少,而且对应位置的类型也要一致。
和数组的区别
使用场景
=====================
对象类型
Object 对象
这样写就是对象类型,可以让它自己推导出对象的属性类型
会自动推导属性的类型
这样也可以定义,但是不推荐这样弄,因为会导致无法获取属性
对象数组,一般会用一个类表示对象
Symbol 符号
ES6新增的,可以查看 https://www.yuque.com/yejielin/mypn47/tq8e2a#984e0115
可以创建出独一无二的符号
取值
emun 枚举类型
定义
像对象一样使用
不赋值的时候默认是0,下一个+1。
当第一个赋值100的时候,下一个还是+1,为101
=====================
空类型
null
null 类型的值,只能是null
但是不指定null类型,赋值null,自动推导是any类型
因为后续可以赋值,因此才会是any
如果报错的话,是因为项目内的ts配置 tsconfig.json 里面默认设置了null赋值的情况,可以通过修改tsconfig.json来调整在项目中是否允许这样赋值
undefined
undefined 类型的值,只能是undefined
=====================
函数相关类型
void 没有返回值
也可以有返回值,有就自动判断,无法判断就是void。
一般都不会写void,交给自动判断。
never 不会发生返回值
一般都是应用在和其他类型联合的。
如下图,定义了一个函数,函数的参数message是一个number类型 或者是 string类型,函数内做了判断,
如果是number类型就执行语句;如果是 string类型就执行语句;
如果传了其他类型进去,编辑器会报错。看样子永远都不会走default这条线。
但是,如果此时有人修改了我这个函数,把参数变为 message : number | string | boolean,如果此时他传了一个boolean进来,就会走default这条线,
这条线是把boolean类型的message一个never类型的变量check,肯定是失败的,此时就提醒你,代码里面还少了一些东西,不允许你这样操作,除非你添加新参数类型boolean的一些操作。
()=> 函数类型
下面红色框就表示函数类型,类似箭头函数。括号内表示有没有参数,以及参数的类型,后面是返回值的类型。
这样写太难看,不直观,因此一般会写成:
type 是定义一个类型
返回值类型
参数类型
如果写了,多一个少一个参数都不行。
有的情况可以自行推导,因此可以不写类型
类型里面的num1和num2(前面的),后面的可以和前面的名字不一样,但是位置顺序和类型要一样,如下。但是不能省略num1、num2这些形参的名字,否则TS会认为类型是any
参数是函数
默认参数值
因此不能传null,可以传undefined。
因此,一般有默认值的参数,都放后面,不要放前面。放前面要传undefined,放后面可以不传任何东西。
参数可选
剩余参数
看下console.log函数的提示,发现用的是…data : any[ ],因此我们才可以通过逗号分隔,传任意东西。
同样,剩余参数的写法,一般都是放后面的
函数的this类型
CodeWHY 老师的一篇关于 this的文章:https://mp.weixin.qq.com/s/hYm0JgBI25grNG_2sCRlTA;
React 和 Vue 慢慢发展,尽可能不用this了,Vue3 的组合API更是没有this。
因此后面的不一定能用得上。
隐式绑定
对于能够推导出this的,是可以这样做不报错。
函数sayHello无法推导出this
项目的ts配置文件 tsconfig.json 会有个默认设置,配置this的。为true时,this不能随便乱用。
解决办法:给this一个类型
但是没办法单独调用,因为这样this是没有绑定任何东西的。上面那个this绑定的是info
如果有其他参数
显式绑定
因此单独使用需要通过call等方法绑定一个东西
apply也可以
两者区别在于参数
call() 方法接受的是一个参数列表,xxfunction.call(绑定this的参数 , arg1, arg2, …)
而 apply() 方法接受的是一个包含多个参数的数组。xxfunction.apply(绑定this的参数, [argsArray])
overload 函数重载 (多个同名函数)
重载,就是同一个函数名,根据参数不同(个数或类型),而使用不同的函数内容。
为什么我们要这样做?下面通过一个需求一步一步解答为什么。
需求:一个add函数,计算a1+a2的值。
(报错,a1和a2无法判断类型)
我们可以使用类型缩小,但是很麻烦,而且无法确定返回值
下图就是函数的重载:
1、通过调用函数时参数的数量、类型不同,查找对应的函数,执行对应的函数体{ }的内容
2、如果没有函数体,就往下查找,直到查找到有匹配的函数体,执行内容。
这样就很方便地解决那个需求。而且更改也很方便。
当然复杂的可以使用函数重载实现。
泛型
说明
泛型可以理解为,这是一个像函数参数一样是一个变量,调用函数的时候把类型传入这个变量,在函数里面把这个类型当做变量一样使用
定义
使用
常用名称(约定,看你自己)
默认类型
=====================
自定义类型
type 类型别名
字面量类型
字符串、数值也是可以作为类型的
字面量类型的值,只能是这字面量
传入其他就会报错
字面量推理
如下,定义了一个请求的方法request,参数是一个url和请求的类型Method。
我们定义了一个选项options,把options传入请求函数,反而报错了。
因为options.method类型是string,而函数要求的类型是Method
解决方案一(推荐):此时定义一个Request类型,就没问题了
解决方案二:通过as断言,告诉TS 这个类型是属于Method就可以了。
断言可以查看 https://www.yuque.com/yejielin/mypn47/czuppx#OlvdZ
解决方案三:字面量推理
as const,把options变成字面量类型,也没问题了