基础篇很大部分都是来自于官网,但里面加入了我自己的理解以及一些实际应用场景的例子
1.基础类型
- Boolean (布尔类型)
let isBool: Boolean = false - Number (数字类型)
let nums: number = 123
// ES6 中的二进制表示法
let binaryLiteral: number = 0b1010;
// ES6 中的八进制表示法
let octalLiteral: number = 0o744;
//NaN,Infinity
let notANumber: number = NaN;
let infinityNumber: number = Infinity;
- String (字符串类型)
let str: string = "123" - Array (数组类型)
let arr0: number[] = [123, 123];
// 使用数组泛型
let arr1: Array<number> = [123, 345];
let arr2: Array<string> = ["123", "345"];
// 泛型后面我会开单章讲
- Tuple (元组类型)
什么叫元组类型,元组类型本质上也属于 数组类型的一种,是数组类型的子集,然后不同的一点在于,元组类型的数据长度是已知的。就是说我们为这里每一位数组中的数据定义类型。那这种类型就叫 ##元组类型##
let tupleArr: [number, string]
tupleArr = [123, "123"]
- Enum (可枚举类型)
这个类型很有作用,至少对于前端来说,因为前端需要用到很多数据字典.
enum Color {Red, Green, Blue}
let c: Color = Color.Green; // 0
let colorName: string = Color[1] // 'Green'
还可以显示设置枚举值
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green; // 2
let colorName: string = Color[1] // 'Red'
这里就是指定了枚举值,这个枚举值不能重复
枚举的可扩充性
enum Color {Red, Green, Blue}
以上代码被编译成JavaScript代码是会是这样
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}))
(Color || (Color = {})),这就意味着,如果您代码运行的当前作用域中已经存在了 Color 变量,那么就会直接在当前 Color 变量上面扩展,那么我们可以多个文件中分散声明我们的枚举类型
enum Color {
Red,
Green,
Blue
}
enum Color {
DarkRed = 3,
DarkGreen,
DarkBlue
}
如果我们采用此种写法,千万要注意每一部分枚举项值的设置,以防止值冲突的出现。
常量枚举
如果我们在声明枚举类型的时候,前面加上 const 关键字,那么这个枚举就是常量枚举。但是此种枚举类型与上面提到的不一样,不一样在哪里呢?看下面代码及编译后的结果:
const enum Color {
Red,
Green,
Blue
}
let c: Color = Color.Green
编译后:
var c = 1 /* Green */;
只剩下值了,这就意味着我们不能用Color[Color.Green]得到对应的字符串了
-
Any (任意类型)
用了这个类型表示我已经不想要TS对这里的检测了
变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型. -
Void (Void 类型)
这个类型代表无,表示我这个没有返回值
声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined 和 null
let unusable: void = undefined; -
Null & Undefined
undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 number 类型的变量:
let num: number = undefined;
2.联合类型
联合类型表示,我这个取值可能为多种类型,我们常见的返回值,因为后端的不统一,比如常见的result可能返回的是200,也可能是个'200',这个时候定义他的类型的时候,为了保持一定的兼容性,可以设置这个的类型为联合类型,但不建议这么做,我们用TS的目的就是为了统一,方便管理和维护.
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
当 TypeScript不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法
上面这个例子里,如果我们要访问myFavoriteNumber.length属性时会报错,因为number没有length属性,但如果访问myFavoriteNumber.toString()就可以,因为这是string|number共有的.
这里要注意,当联合类型被赋值的时候,会存在类型推导的抢断出一个类型,这个时候你就可以访问这个类型的属性和方法
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
console.log(myFavoriteNumber.length); // 5
myFavoriteNumber = 7;
console.log(myFavoriteNumber.length); // 编译时报错
3.接口interface
interface Person {
readonly name: string; // 只读属性,不能被二次赋值
age: number;
gender?: boolean //可选属性
[key: string]: any; // 任意属性
}
let tom: Person = {
name: 'Tom',
age: 25,
...
};
这里有个点一定要注意:一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
意思就是如果你定义了任意属性,那么这个接口里的所有属性会被这个任意属性约束,所有属性的值的类型必须是任意属性值类型的类型或者子集,上面这段代码如果改成
interface Person {
readonly name: string; // 只读属性,不能被二次赋值
age: number;
gender?: boolean //可选属性
[key: string]: string; // 任意属性
}
就会报错,这里的任意类型是string,而必须属性age和可选属性gender都不是string类型或者它的子集,所以就会报错.
4.类型推导
let hello = 'hello world'
hello = 2
// Type '2' is not assignable to type 'string'.ts(2322)
它将等价于
let hello: string = 'hello world'
hello = 2
初始定义赋值时如果没有指定类型,TS会按值来推导类型.
但如果初始定义时没有赋值,则会被推导为any类型.
let hello
hello = 2
hello = 'hello world'
5.函数类型
函数表达式:
let sum = function (x: number, y: number): number {
return x + y;
};
这其实不是一完整的TypeScript表达式,因为只对右边的匿名函数做了类型定义,左边的变量会存在一个类型推导过程.完整的写法:
let sum:(x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
};
在 TypeScript 的类型定义中的 => 用来表示函数的定义,箭头左边是输入类型,箭头右边是输出类型,不要和 ES6 的箭头函数混淆。
6.类型断言
什么是类型断言?简单的意思就是我知道自己在做什么,你不用检测了.
断言的写法有两种,<类型>和as
let str: string = "this is a string";
// 尖括号<>
let strLength1: number = (<string>str).length;
// as,建议用这写法,在React 的 tsx 语法中必须使用这种写法
let strLength2: number = (str as string).length;
7.泛型
这是一个重要的概念,这里我会在后面开一个单章以及我个人的一个使用例子来着重讲解下