一、类型声明
(一) 类型声明
-
类型声明是TS非常重要的一个特点
-
通过类型声明可以指定TS中变量(参数、形参)的类型
-
指定类型后,这些指定的类型也称为“静态类型”为,就是你一旦定义了,就不可以再改变了。当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错
-
简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值
-
语法:
-
let 变量: 类型; let 变量: 类型 = 值; function fn(参数: 类型, 参数: 类型): 类型{ ... }
-
(二)定义变量
之前在js中定义一个变量可以这样定义:
var num=12; //num是数值类型的
var num="hello" //num是字符类型的
也就是说我们在给变量赋值的时候可以不指定变量的数据类型,数据类型根据变量的值而定。
但是在ts中定义一个变量要给变量指定它的数据类型。在ts中变量的使用分为两步:1.声明变量并指定类型 2.给变量赋值。
//第一种定义方式:
let age : number; //age为number类型
age=12;
//第二种定义方式:
let age:number=12;
二、类型注解和类型推断
1.类型注解
为了方便大家更好的理解给变量添加数据类型,我们可以引入“类型注解”的概念。
类型注解:是一种为变量添加类型约束的方式。
程序员 和 TS 有个约定。约定了什么类型,就只能给变量赋什么类型的值
比如刚才我们给age指定的类型为number,这时候如果给age赋值的类型为number那就会报错
我们现在使用的编辑器是vscode,有一个好处就是当我们把鼠标放在变量上的时候,相应的数据类型就会显示出来。
2.类型推断
自动类型判断
- TS拥有自动的类型判断机制
- 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
- 所以如果你的变量的声明和赋值时同时进行的,可以省略掉类型声明
let money= 888;
这时候我并没有显示的定义变量num
是一个数字类型,但是如果你把鼠标放到变量上时,你会发现 TypeScript 自动把变量注释为了number
(数字)类型,也就是说它是有某种推断能力的,通过你的代码 TS 会自动的去尝试分析变量的类型。
接下来我们来计算两个数之和:
const num1 = 10;
const num2 = 20;
const add = num1 + num2;
console.log(add);//30
这个时候num1和num2没有定义数据,得到的结果也是正确的。
我们尝试封装一个两个数相加的方法。
function total(a,b){
return a+b;
}
console.log(total("皮皮虾",30));
a和b会显示为any类型。这时候如果你传字符串,你的业务逻辑就是错误的,所以你必须加一个类型注解
.修改代码:
function total(a:number,b:number){
return a+b;
}
console.log(total(20,30));
在写 TypeScript 代码的一个重要宗旨就是每个变量,每个对象的属性类型都应该是固定的,如果你推断就让它推断,推断不出来的时候你要进行注释。
三、基本静态类型
TypeScript 中的数据类型分为两大类:1 原始类型(基本数据类型) 2 对象类型(复杂数据类型)。有的也说基本静态类型和对象类型。
TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。
-
类型
类型 例子 描述 number 1, -33, 2.5 任意数字 string ‘hi’, “hi”, hi
任意字符串 boolean true、false 布尔值true或false 字面量 其本身 限制变量的值就是该字面量的值 any * 任意类型 unknown * 类型安全的any void 空值(undefined) 没有值(或undefined) never 没有值 不能是任何值 object {name:‘孙悟空’} 任意的JS对象 array [1,2,3] 任意JS数组 tuple [4,5] 元素,TS新增类型,固定长度数组 enum enum{A, B} 枚举,TS中新增类型 1.数字类型(number)
数字类型:包含整数值和浮点型(小数)值。
// 数字类型:整数
let age : number = 18;
// 数字类型:小数
let score : number = 88.6;
2 .字符串类型(string)
var str:string='this is ts';
str='周杰伦'; //正确
str=123; //错误
3.布尔类型(boolean)
//es5的写法 :
var flag=true;
flag=456;
//typescript中为了使编写的代码更规范,更有利于维护,增加了类型校验
// 写ts代码必须指定类型
var flag:boolean=true;
// flag=123; //错误
flag=false; //正确
console.log(flag);
4.undefined 、 null
共同特点:只有一个值,值为类型本身
undefined:表示声明但未赋值的变量值(找不到值)。
null:表示声明了变量并已赋值,值为 null(能找到,值就是 null)
类型为:undefined
let food : undefined = undefined
//类型为:null
let money : null = null
5.symbol
var b=Symbol();
var c=Symbol();
console.log(b==c);
var c=Symbol("我是描述地址的属性");
//获取描述信息
console.log(c.description);
//第一种定义对象属性
var obj={
name:'kelly',
age:12,
// [c]:'中山西路'
}
//第二种定义属性的方法
obj[c]="江山路8888";
console.log(obj);
//获取属性
console.log(obj[c])
tsconfig.js中需要更改compilerOptions选项下的lib属性,这样就可以正常解析了。
"lib": ["es6","DOM","ES2019"],
6.任意类型(any)
有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any
类型来标记这些变量:
let userInput: any = 10;
userInput = "用户输入的是字符串";
userInput = false; // OK
当你只知道一部分数据的类型时,any
类型也是有用的。 比如,你有一个数组,它包含了不同的类型的数据:
let list: any[] = [1, true, "free"];
list[1] = 100;
any的用法:在我们获取元素设置样式的时候,需要制定类型,这时又不确定数据类型,可以设置为any
var box=document.querySelector("#box"); //错误写法
box.style.color="red";
var box:any=document.querySelector("#box"); //正确写法
box.style.color="red";
7.Void
某种程度上来说,void
类型像是与any
类型相反,typescript中的void表示没有任何类型,一般用于定义方法的时候方法没有返回值。
function run(): void {
console.log("没有任何返回数据");
}
声明一个void
类型的变量没有什么大用,因为你只能为它赋予undefined
和null
:
let grass: void = undefined;
8.never
never
类型表示的是那些永不存在的值的类型。是其他类型 (包括 null 和 undefined)的子类型,也可以赋值给任何类型,代表从不会出现的值。
这意味着声明never的变量只能被never类型所赋值。 never
类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never
类型,当它们被永不为真的类型保护所约束时。
//never 类型
var a:never;
a=123; //错误的写法
a=(()=>{ //正确写法
throw new Error('错误');
})()
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}
// 推断的返回值类型为never
function fail() {
return error("Something failed");
}
// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
while (true) {
}
}
四、数组类型
(1)数组
TypeScript像JavaScript一样可以操作数组元素。 有两种方式可以定义数组。 第一种,可以在元素类型后面接上 []
,表示由此类型元素组成的一个数组:
let arr: number[] = [1, 2, 3]; //正确
let arr:number[]=["hello",1,2,3]; //错误,数组中的数据类型不是声明的数据类型
第二种方式是使用数组泛型,Array<元素类型>
:
let list: Array<number> = [1, 2, 3]; //正确
let list2:Array<string>=["javascript",'css',2] //错误
数组中对象类型的定义:
const ice: { name: string, price: Number }[] = [
{ name: "哈根达斯", price: 56 },
{ name: "八喜", price: 32 },
];
const coffee:{name:string,price:Number}[]=[
{name:'海盐芝士',price:35},
{name:"陨石拿铁",price:32}
]
这种形式看起来比较麻烦,而且如果有同样类型的数组,写代码也比较麻烦,TypeScript 为我们准备了一个概念,叫做类型别名
(type alias)。
比如刚才的代码,就可以定义一个类型别名
,定义别名的时候要以type
关键字开始。现在定义一个goods
的别名。
type goods = { name: string, age: Number };
有了这样的类型别名以后哦,就可以把上面的代码改为下面的形式了。
type goods= { name: string, price: Number };
const ice:goods[]=[
{ name: "哈根达斯", price: 56 },
{ name: "八喜", price: 32 },
];
const coffee:goods[]=[
{name:'海盐芝士',price:35},
{name:"陨石拿铁",price:32}
]
console.log(coffee[1].name); //陨石拿铁
(2)元组Tuple
元组属于数组的一种。 元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为 string
和number
类型的元组。
let person: [string, number];
person= ['Kelly', 20]; // 正确
x = [20, 'kelly']; // Error
当访问一个已知索引的元素,会得到正确的类型:
console.log(person[0].substr(1)); // 正确
console.log(person[1].substr(1)); // Error, 'number' does not have 'substr'
当访问一个越界的元素,会使用联合类型替代:
person[3] = 'world'; // OK, 字符串可以赋值给(string | number)类型
console.log(person[5].toString()); // OK, 'string' 和 'number' 都有 toString
x[6] = true; // Error, 布尔不是(string | number)类型
(3)枚举(enum)
enum
类型是对JavaScript标准数据类型的一个补充。 像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。
随着计算机的不断普及,程序不仅只用于数值计算,还更广泛地用于处理非数值的数据。例如:性别、月份、星期几、颜色、单位名、学历、职业等,都不是数值数据。 在其它程序设计语言中,一般用一个数值来代表某一状态,这种处理方法不直观,易读性差。
如果能在程序中用自然语言中有相应含义的单词来代表某一状态,则程序就很容易阅读和理解。
也就是说,事先考虑到某一变量可能取的值,尽量用自然语言中含义清楚的单词来表示它的每一个值, 这种方法称为枚举方法,用这种方法定义的类型称枚举类型。
格式:
enum 枚举名 {
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数],
} ;
定义表示颜色的枚举类型:
//颜色
enum Color {red,orange,yello,green};
let c:Color=Color.yello;
console.log(c); // 2
默认情况下,从0开始为元素编号。 你也可以手动的指定成员的数值。
比如,我们用一个变量表示状态,1代表成功,2代表失败。
enum Flag {success=1,error=2};
let s:Flag=Flag.success;
console.log(s); //1
枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为2,但是不确定它映射到Color里的哪个名字,我们可以查找相应的名字:
enum Color {red=1,orange,yello,green}
let colorName: string = Color[2];
console.log(colorName); // 显示'orange'因为这里的代码里它的值是2
3.类类型
class Person {}
const lucky: Person = new Person();
这个意思就是lucky
必须是一个Person
类对应的对象才可以。我们还可以定义一个,并确定返回值。代码如下:
4.函数类型
定义一个函数并确定返回值,函数类型后续会详细说。
const run: () => string = () => {
return "run";
};