??本节介绍TypeScript中的基础类型及变量声明方式的说明。TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。基础类型包括:数字,字符串,结构体,布尔值等。
学习视频
TS学习笔记二:基础类型与变量定义
B站视频
TS学习笔记二:基础类型与变量定义
??TypeScript基础类型中包括数字,字符串,结构体,布尔值等。变量指定类型时使用“:”加类型名指定变量类型。
1. 布尔值
??布尔类型,使用boolean什么,定义方式:let isOk:boolean = false;
2. 数字
??数字类型,包括整数、浮点数等都是用number进行定义, 除了支持十进制和十六进制字面量,Typescript还支持ECMAScript 2015中引入的二进制和八进制字面量。定义方式如下:
let a :number = 1;
let a :number = 0xf00e;
let a :number = 0b1010;
let a :number = 0o711;
3. 字符串
??使用标识符string定义字符串,可使用“””或“’”标识字符串,定义方式:
let str:string = ‘222’
let str:string = “34234”;
??也可使用模板字符串,定义多行文本和内嵌表达式,使用`进行定义,使用${}嵌入表达式,定义方式如下:
let a:string = ‘2’;
let b:number=22;
let str:string = `This is ${a} and ${b+1}`;
??也可以使用如下定义,结果一致:
let str:string = ‘This is ’ + a + ‘ and ’ + (b+1);
4. 数组
??TypeScript中有两种方式可以定义数组。 第一种,可以在元素类型后面接上[],表示由此类型元素组成的一个数组:let list: number[] = [1, 2, 3];
??第二种方式是使用数组泛型,Array<元素类型>:
let list: Array<number> = [1, 2, 3];
5. 元组
??元组是TypeScript中特有的,可以定义一个已知数量和类型的数组,且各个元素的类型不必相同,定义方式和数组类型,具体如下:
let x :[number,string,boolean] = [1,’2’,false];
??当使用索引进行访问时,可以得到索引所对应的元素的具体类型,如x[0]可获取到第0个元素的数据类型,并可以使用该类型对应的方法。
??当访问越界的元素时,元素的类型使用联合类型代替,即指定的所有类型中任何一种,如给x[4] = 3,此时下标4已经越界,且定义的时候没有指定具体的类型, 这个时候使用number或string或boolean中的任何一个类型来进行标识,设置值的时候只要是这三个类型中的任何一个都可以,超出这三个的范围则不行。获取元素时,对应的类型也是联合类型,可访问这三个属性都具有的共工属性或方法,如x[4].toString()可正常执行,因为number、string和boolean都具有toString方法。
??此处的联合类型是一个高级类型,将在后续的章节中介绍到。
6. 枚举
??枚举是TypeScript补充的类型,使用enum进行定义,像其它高级语言一样,使用枚举类型可以为一组数组赋予更加友好的名字,定义方式如下:
enum Color{Blank,Blue,Red};
let color:Color = Color.Blank;
??默认情况下,枚举的下标是从0开始,即上述例子中的Blank的值是0,Blue的值是1,下一个是上一个的值+1。也可以通过手动指定的方式设置开始值,设置方式如下:
enum Color{Blank = 1,Blue,Red};
let color:Color = Color.Blank;
??也可以给全部值都使用手动赋值,具体定义方式如下:
enum Color{Blank = 1,Blue = 2,Red = 3};
let color:Color = Color.Blank;
??枚举类型也可以使用枚举的值得到对应的名字,获取方式如下:
enum Color{Blank = 1,Blue = 2,Red = 3};
let colorName:string = Color[2];
7. 任意值
??编程阶段不清楚类型的变量,为了烧开类型检查器,可以使用任意值进行标识,关键字为any,定义方式:let a:any = 121,a = ‘2’;
可以设置任意类型。
??可以对现有代码进行改写的时候,能够允许在编译时包含或移除类型检查,和Object有类似作用,但Object类型的变量只允许给它赋任意值,但是不能在它上面调用任意的方法,即使方法存在。
??也可以在定义数组时只知道一部分数据类型的时候进行使用,如:let arr:any[] = [1,’2’,’4’];
8. 空值
??关键字为void,与any类型相反,标识没有任何类型,通常用于函数的返回值的类型设置,定义如下:
function a():void{}
??声明void类型的变量没有意义,只能赋予undefined和null。
9. Null和Undefined
??对应js中的原生类型null和undefined,和空值void类似,本身的类型用处不大,定义方式如下:
let a:undefined = undefined;
let b:null = null;
??默认情况下null和undefined是所有类型的子类型,可以把null和undefined赋予number等类型的变量。然而当指定了--strictNullChecks
标记,null和undefined只能赋值给void和它们各自。
10. Never
??Never类型标识永不存在的值的类型,可用于哪些总是会抛出异常或者根本不会有返回值的函数表达式或箭头函数表达式的返回值类型。
??Never是任何类型的子类型,也可以赋值给任何类型,没有类型是naver的子类型或可以赋值给never类型(除了never类型本身之外),即使any也不可以赋值给never。使用示例如下:
function error(msg:string):never{//函数不可能有返回值
throw new Error(‘error’);
}
function fail(){//推断类型为never
return error(‘ss’);
}
function loop():never{//函数无法结束
while(true){
}
}
11. 类型断言
??当能明确知道比现有类型更具体的类型的时候,可以使用类型断言进行设置,类型断言好比其它语言中的类型转换,只是不进行特殊的数据检查和解构,没有运行时的影响,只是在编译阶段起作用。有两种使用方式:
一是尖括号的语法:
let a:any = ‘fsfds’;
(<string>a).indexOf();
二是as语法:
let a:any = “fsdfds”;
(a as string).indexOf();
两种方式是等价的,ts中使用jsx时,只允许使用as语法。
??变量的声明包括var、let和const等方式,不同的定义方式具有不同的效果及注意事项,有自己的作用域及规则。
1. var声明
??var是早期的变量定义关键字,如:var a = 10;可以定义任意类型的变量,也可以函数内部定义变量:
function a(){
var b = 10;
}
??也可以因为作用域的延伸,在函数内部使用外部的参数,定义方式如下:
function a(){
let b = 1;
function c(){
let d = b+1;
}
}
??var声明的变量,存在变量提升的情况,可以在包含它的函数、模块、命名空间或全局作用域内部任何位置被访问,代码块也没有影响,因此多次声明同一个变量并不会报错,而且在定义之前进行变量访问也不会报错,也可以进行多次定义,只是定义的变量只有一个实例。
a = 1;
var a;
2. Let声明
??let声明和var类型,如let a= 20;但具体的作用域规则和var是有区别的,当用let声明一个变量,它使用的是词法作用域或块作用域。不同于var声明的变量可以在包含它们的函数外访问,块作用域变量在包含他们的块或for循环之外是不能访问的,示例如下:
function a (){
let a = 100;
if(a){
let b = 1;
}
return b;//此处会报错,无法访问变量b但是如果b变量是使用var声明的,则可以访问。
}
??catch中的变量也是具有同样的作用域规则,块级作用域的变量不能在声明之前访问,var声明的变量就可以,如:
a = 1;//此处会报错,变量未定义
let a ;
??可以在一个拥有块作用域变量被声明前获取它。 只是我们不能在变量声明前去调用那个函数。
function foo() {
return a;
}
// 不能在’a’被声明前调用’foo’, 运行时应该抛出错误
foo();
let a;
??let声明的变量不能重复定义,即同一个各作用域内,同样名称的变量只能有一个,重复定义会报错,示例如下:
let a = 1;
let a = 1;//此处会报错,变量重复定义,使用var时就不会
3. Const 声明
??const声明的变量和let类似,但其值在定义时赋值后就不能再次更改,其作用域规则和let类型,不可重复定义,只是块级作用域,不能在声明之前访问,唯一的区别就是不可重复赋值。
const a = 1;
a = b;//此处会报错。
??修改const定义的对象内部的属性是允许的,具体如下:
const obj = {
a:1,
b:2
}
obj = {};//此处会报错。
obj.a = 2;//修改属性可以
??所用变量除了需要有修改的过程,都建议使用const。
4. 解构数组
??数据解构,使用方式如下:
let a = [1,2,3];
let {c,d,e} = a;
//此时c = 1;d = 2,e = 3;类似于使用了let c = a[0]这样的定义方式。
??也可以使用解构进行变量的值交换,如[a,b] = [b,a],也可用于函数的参数,如下:
function ([a,b]:[number,number]){
}
??若只取一部分数据,则使用…剩余参数的方式进行定义,使用方式如下:
let [a ,...other] = [1,2,3,4,5]; //此时a为1,other为[2,3,4,5]
??也可以直接忽略其余的参数,如:
let [a] = [1,2,3,4]; //此时a为1,其余的将会丢弃。
??也可以忽略指定元素,如:
let [a,,b,c] = [1,2,3,4]//此时a为1,b为3,c为4,2将被忽略。
5. 对象解构
??对象解构如下:
let obj = {
a:1,
b:2,
c:3
}
let {a,b} = obj;//此时a= 1,b=2;
??不需要的属性可以直接忽略,相当于:let a = obj.a ,let b = obj.b定义并赋值。也可以使用没有声明的赋值,如:
({a,b} = {a:’2’,b:12})
??可以给属性不同的名字,如:let {a:a1,b:b1} = obj;此处的:不是用于指定其类型的,而是指定其新名称的。
??也可以设置默认值,设置后在属性为undefined时使用缺省值,如下:
function aa (obj:{a:string,b?:number}){
let {a,b=111} = obj;
}
??示例如果参数中的b为undefined,参数obj的属性a和b都有值。
6. 函数声明
??解构也可用于函数声,示例如下:
type C = {a:string,b?:string};
function f({a,b}:C):void{
}
??也可以指定参数的默认值:
function f({a,b} = {a:””,b:0}):void{
}
??此实例中调用f时,参数会有默认值。