前言:

        上一节介绍的是TypeScript基本数据类型里几个特殊的类型(unknown、any和never),这一节继续介绍Typescript的普通数据类型

普通数据类型:

一、字面量类型

可以理解为将类型限定为某个字面量,在实际开发过程中基本使用不到

let a: 10; // 此处就相当于创建了一个类型叫“10”,则限定变量a的值就是字面量的值
a = 12; //报错,也就是说变量a只可以赋值为10
let sex:"male" | "female"; // 在实际运用中,一般字面量用的不是很多
sex = "male";
sex = "female";

二、number - 数字类型

let a: number = 0;
 // // 描述:任意数字

三、string - 字符串类型

let a: string = "abc";
// //描述:任意字符串

四、boolean - 布尔值

let a: boolean = true;
let b: Boolean = false;
// //描述:布尔值

五、void - 空值

function fn(): void{
    return 12; // 声明类型之后还设置返回值,则报错

}

此处规定函数的返回值是空值,但是依旧设置了返回值“12”,就会报函数返回值类型错误

typescript 存取器 typescript declare type_数组

 但是需要注意的是,返回值类型设置为空值不代表不允许有返回值,依旧可以发挥null,或者undefined

function fn(): void{
    return null; // 都不报错
    return undefined;
}

描述:空值,与never相似,never表示不存在,而void表示存在但是为空,只能赋值为undefined和null,一般对于变量以及参数不声明为void类型,因为意义不大

补充:①对于变量:不声明类型,不赋予初值,则默认为any类型;

                                 不声明类型,赋予初值。根据初值进行类型推断;

           ②对于函数返回值:不声明类型,不赋予初值,则默认为void类型;

                                            不声明类型,赋予初值。根据初值进行类型推断;

六、object - 对象类型

let a:object;

        对于以上代码,在Javascript中并没有什么意义,因为在js中对象类型很庞大,以至于很多文章中都提出了“js万物皆对象”这种比较偏激的概念,我们在开发过程中,并不会使用如上的类型限制声明,因为一个变量是不是object类型,对于我们来说并没有什么约束,我们更多的使用得是,限制对象中的某一些属性,而不是限制它是不是一个对象,如下

let b:{
    name:string = ,
    age:number,
}
b.name = 123; // 报错,不能将number类型分匹配给string类型
b={}; // 报错 缺少属性name,age
b={name:"hello"}; // 报错,缺少属性age
b={name: "hello",age:12,sex:"男"} // 对象只可以指定已知的属性,而sex不在已知属性中
b={name:123,age:"hello"} // 报错,类型报错

如果有一些情况,我们不能明确的知道对象上的属性是否必填,则可以使用这种方法

let c:{name:string,age?:number};
c={name:"hello"}; // 此处并不报错
c={age:12} // 报错,提示缺少name属性

还有的时候,我们需要按需拓展对象上的属性,并且不能明确的知道属性名称,则可以使用这种方法

语法:[属性名: 属性名类型]:属性值类型

 下例中限定了对象d为必须属性,而剩余的属性可以根据需求任意拓展(类型限定为any),但是这种any只能用在开发环境的时候,在生产环境时,所有的数据类型都可以限定,我们就需要将any类型替换为某一种类型或某几种类型

let d: {name:string,[hello: string]: any};
// 需注意,索引签名参数,即属性名类型必须为strig或者nunber类型
d={name:"zhangsan",age:123,sex:true};

七、function - 函数类型

        与对象类型类似的是,我们在定义函数类型时并不关注是否为函数类型,而注意力会放在函数的结构上,如形参个数,形参类型,函数返回值等,这几点其实在上一节中已经使用过

let e:(a:number,b:number)=>number;

如上代码,可以理解为定义了一个函数e,须有两个类型为number类型的参数,其该函数返回值类型为number类型

对于函数e,我们限制了三个方面:

        1.参数个数

        2.参数类型

        3.返回值类型

例:对于e进行赋值

e = function(params1,params2){
    return params1 + params2;
} // 此处可以正常进行赋值
e= function(params1,params2,params3){
    return params1 + params2 + params3;
} // 此处多传一个参数就会报错
e = function(params1,params2){
    return true; // 返回值类型报错,上方规定为number类型
} 
e = function(params1:string,params2){ // 此处报错不能将string分配给number
    return params1 + params2;
}

八、array - 数组

在js中,对于数组内部的存储内容并没有进行类型限制,也就是说,我们可以在一个数组中存储任意类型的数据,甚至是另一个数组形成二维数组,如

let f = ["hello",123,true,{},[1,2,3]];
f.forEach(item=>console.log(item))

输出:

typescript 存取器 typescript declare type_javascript_02

 但在开发环境中,我们一般只希望数组内数据格式统一,在使用过程中也一般只储存相同类型的数据,但并没有具体的语法要求,而Typescript中的数组就可以限制数组内得数据类型

let f: string[];
f = ["hello","world","hello"];
f = [123,456] // 将number类型得数据存入数组中,就会报错
let g: number[]; // 数字数组
// 另一种写法:
let h: Array<string>
h = ["张三","李四","王五"]
h = [123,456] // 报错

如上的代码段,限定了具体的数组存储的内容是什么类型,保证了数组内部格式统一

九、tuple - 元组

元组可以看作是数组的拓展,一种规定了长度的数组,一般在明确了元素的数量以及类型时,可以使用元组,在存储效率上,元组的效率比数组要高。

let i: [string,number];
i = ["张三",123]; // 正常赋值
i = [123,"hello"] // 类型对应错误,报错
i = ["张三",123,456] // 元素数量对应错误,报错

但是元组是可以拓展的,使用数组的push()方法进行数据插入,发现数据插入成功

let i: [string,number];
i = ["张三", 123]
i.push(123);
console.log(i) // ["张三", 123, 123]
console.log(i.length) // 3

十、enum - 枚举

枚举类型是ts中新引入的一个数据类型,用于定义一些带名字的常量,来清晰的表现意图或者创建一组有区别的用例

1.数字枚举

enum Diretion{
     up = 1,
     down,
     left,
     right,
}

如上代码,定义一个数字枚举类,若将某个枚举成员进行初始化,则其余成员在这个成员的基础之上进行自增,即

Diretion.up = 1,Diretion.down = 2,Diretion.left = 3,Diretion.up = 4

 又定义:

enum NumberAdd{
     one,
     two = 5,
     three,
     four,
}
console.log(NumberAdd.one); // 0
console.log(NumberAdd.three); // 6

若完全不进行初始化,则枚举成员从0开始自增

需注意的是,数字枚举具有反向映射

即:

console.log(Diretion[1]); // up
console.log(Diretion.up); // 1
console.log(Diretion[2]); // down

如上文中进行初始化时,不进行初始化的枚举成员要么从第一位开始,要么放在由常量初始化的枚举成员之后,,但是不能放在由非常量初始化的枚举成员之后,例如

function initValue(){
     return 12
}
enum numberEnum{
     a = initValue(); // 12
     b; // 报错,枚举成员必须拥有初始化表达式
}

 枚举成员b放在了由函数initValue 返回值赋值的枚举成员之后,当枚举成员赋值时未使用常数赋值,则会被认为时字符串枚举,而字符串枚举成员是无法自增默认赋值的。

 2.字符串枚举

如上文所述,字符串枚举并不能被Ts编译器初始化

enum stringEnum{
    a = "张三",
    b = "李四",
    c, // 报错
}

而如果为赋初始值的枚举成员在第一项时,会自动赋值为0,标题中形容的“字符串枚举”并不是所哟的枚举成员都是字符串,只是我们主观判断为“字符串枚举”

3.异构枚举

相当于混合了数字成员和字符串成员的枚举类,但一般没有什么特殊的意义

enum Heterenum {
     no = 0,
     yes = "yes",
}

4.常量枚举

常量枚举不同于常规的枚举,他们在编译阶段会被删除,常量枚举成员在使用的地方会被内联进去

const enum ConstDiretions{
     up,
     down,
     left,
     right,
 }

let letdiretion = [ConstDiretions.up,ConstDiretions.down];

编译之后就会变为

var letdiretion = [0 /* up */, 1 /* down */];

这种常量枚举,对于性能的提升是较为友好的。