原始数据类型
布尔值、数字、字符串、null、undefined、Symbol(ES6)、BigInt(ES10)
// 布尔值
let isDone: boolean = false;
// 数字
let decLiteral: numbe = 6;
let notAnNumber: number = NaN;
let infinityNumber: number = Infinity;
let binaryLiteral: number = 0b1010; // ES6 中的二进制表示法
// 字符串
let myName: string = 'Tom';
let sentence: string = `Hello, my Name is ${myName}`;
// 空值 void:表示没有任何返回值的函数;仅能赋值为null/undefined的变量
function alertName(): void {
alert('My name is Tom!');
}
let unusable: void = undefined;
注意:
-
使用构造函数Boolean创造(new)的对象不是布尔值,返回的是一个Boolean对象。直接调用Boolean返回一个boolean类型。同理其他基本类型(除了null 和 undefined)。
let createByNewBoolean: Boolean = new Boolean(1); let createByBoolean: boolean = Boolean(1) -
void 和 null / undefined 的区别
undefined 和 null 是所有类型的子类型,可以赋值给number / string ... 类型的变量(需要在
tsconfig.json配置文件中"strict": false;),但是void不行。let num: number = undefined; let u = undefined; let num: number = u; let v = void; let num: number = v; // Type 'void' is not assignable to type 'number'.
任意值(any)
允许赋值为任何类型
- 声明为任意值的变量,对它的任何操作,返回的内容类型都是任意值;
- 声明时未指定类型的变量,默认为任意值类型;
- 如果定义的时候没有赋值,之后不管有没有赋值,都会被推断成
any类型而不被类型检查。
类型推论(Type Inference)
TypeScript 会在没有明确指定类型的时候推测出一个类型
let myNumber = 'seven';
myNumber = 7;
// Type 'number' is not assignable to type 'string'.
// ----- 等价于 -----
let myNumber: string = 'seven';
myNumber = 7;
// ----- 声明不赋值默认为any类型 ----
let myNumber;
myNumber = 'seven';
myNumber = 7;
联合类型(Union Types)
使用
|分隔每个类型,取值可以为多种类型中的一种
- 在不确定联合类型的变量类型时,只能访问联合类型的所有类型里共有的属性和方法;
- 联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型;在赋值类型变化时可能导致报错。
对象的类型 —— 接口(Interfaces)
赋值的时候,变量的形状必须和接口的形状保持一致。
// 建议接口的名称加上I前缀
interface IPerson {
readonly id: number, // 只读属性
name: string;
age?: number; // 可选属性
[key: string]: any // 任意属性
}
let tom: IPerson = {
id: 1,
name: 'Tom',
age: 25
}
说明:
只读属性的约束在第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候。
```
interface IPerson {
readonly id: number
name: string
}
let tom: IPerson = {
name: 'Tom'
}
tom.id = 1212; // error
```
数组的类型
// 1. 类型 + 方括号表示
let arr1: number[] = [1, 3, 4];
// 2. 数组泛型
let arr2: Array<number> = [1, 2, 3];
// 3. 接口表示(较复杂,很少用来表示数组)
interface INumberArray {
[index: number]: number
}
let arr3: INumberArray = [1, 3, 4];
接口表示类数组
// 类数组转成数组
args = Array.prototype.slice.call(arguments)
函数的类型
函数声明
// ****** JavaScript ******
// 函数声明(Function Declaration)
function Sum(x, y) {
return x + y;
}
// 函数表达式(Function Expression)
let mySum = function(x, y) {
return x + y;
}
// ***** TypeScript ******
// 参数必须和声明时的对应,不可以多也不可以少
function Sum(x: number, y: number): number {
return x + y;
}
let mySum = function (x: number, y: number): number {
return x + y;
} // mySum 通过赋值操作进行类型推断获得
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
}
// (x: number, y: number) 输入定义 => number 输出定义
用接口定义函数的形状
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1;
}
可选参数?
注意:可选参数后面不允许出现必须参数。
function Sum(x: number, y?: number) {
if (y) return x + y;
return x;
}
let sum1 = Sum(1);
let sum2 = Sum(1, 0);
参数默认值
添加了参数默认值的TypeScript会识别为可选参数,且不受可选参数必须接在必须参数后面的限制。
function Sum(x: number, y: number = 0) {
return x + y;
}
关于默认参数可参考【ES6中函数的参数默认值】
剩余参数
在ES6中,可以使用
...rest的方式获取函数中的剩余参数。
function push(array, ...items) {
items.forEach(item => {
array.push(item);
})
}
let a: any[] = [];
push(a, 1, 2, 3);
重载
允许多个函数接受不同类型或数量的参数,作不同的处理。
-
联合类型
function reverse (x: number | string): number | string | void { if (typeof x === 'number') return Number(x.toString().split('').reverse().join('')); else if (typeof x === 'string') return x.split('').reverse().join(''); }但是不能准确表达输入为数字的时候,输出为数字;输入为字符串的时候,输出为字符串。
-
使用重载定义
function reverse(x: number): number; function reverse(x: string): string; function reverse(x: number | string): number | string | void { // ... } // 重复多次定义 reverse,前几次为函数定义,最后一次为函数实现。 // TypeScript会优先从最前面的函数开始匹配,所以多个函数定义如果有包含关系需要优先把精确的定义写在前面。