# 基本类型 LIST

### TypeScript基本类型有如下几种：

#####Boolean
#####Number
#####String
#####Array
#####Tuple
#####Enum
#####Any
另外还有void类型，主要用于标识方法返回值的类型。
```javascript
// Boolean
let isDone: boolean = false;
isDone = true;

// Number
let num: number = 1;        // 整数
num = 2.5;                  // 小数
num = 0xf00d;               // 十六进制
num = 0b0101;               // 二进制
num = 0o123;                // 八进制

// String
let str: string = 'Hello world';
let content: string = `${str} too`;                 // 使用表达式拼接字符串时，需要使用(`)符号将拼接内容包括起来

// Array
let numbers1: number[] = [1, 2];
let numbers2: Array<number> = [1, 2, 3];            // 另外一种定义数组类型的方式，与nunber[]等价

// Tuple（元组类型）
let t: [string, number] = ['No.', 1];
t = ['This is No.', 2];                             // 值类型与定义的一致，编译通过。
//t = [2, 'This is No.'];                           // 值类型与定义的不一致，编译失败，提示错误。

// Enum（枚举）
enum Operator1 { Add, Update, Delete, Select };
let opt1: Operator1 = Operator1.Add;                // opt1的值为0。取枚举项的默认值。

enum Operator2 { Add = 1, Update, Delete, Select };
let opt2: Operator2 = Operator2.Update;             // opt2的值为2。当某一项设置了值后，后续项的值都顺次加1。
let opt2Name: string = Operator2[2];                // opt2Name的值为Update。通过值索引可以得到枚举项的名称。
```

#####另外，Any类型是一个特殊的类型。它表示当前对象的类型由具体的值的类型来确定，它可以适用于任何强类型。
```javascript
// Any
let obj: any = 'This is a string.';
obj = 1;
obj = [1, 2];
obj = false;
obj = {};
obj = function () { return false; };
```

#####Any类型的值可以通过强制类型转换将值转换成目标类型

```javascript
 // 强制类型转换
 let obj1: any = 'This is a string.';
 let len: number = (<string>obj1).length;
 len = (obj1 as string).length;
```

#####将以上代码进行编译后将转换成ES5标准的JavaScript源码，如下
```javascript

// Boolean
var isDone = false;
isDone = true;
// Number
var num = 1;        // 整数
num = 2.5;          // 小数
num = 0xf00d;       // 十六进制
num = 5;            // 二进制
num = 83;           // 八进制
// String
var str = 'Hello world';
var content = str + " too";                             // 使用表达式拼接字符串时，需要使用(`)符号将拼接内容包括起来
// Array
var numbers1 = [1, 2];
var numbers2 = [1, 2, 3];                               // 另外一种定义数组类型的方式，与nunber[]等价
// Tuple（元组类型）
var t = ['No.', 1];
t = ['This is No.', 2];                                 // 值类型与定义的一致，编译通过。
//t = [2, 'This is No.'];                               // 值类型与定义的不一致，编译失败，提示错误。
// Enum（枚举）
var Operator1;
(function (Operator1) {
    Operator1[Operator1["Add"] = 0] = "Add";
    Operator1[Operator1["Update"] = 1] = "Update";
    Operator1[Operator1["Delete"] = 2] = "Delete";
    Operator1[Operator1["Select"] = 3] = "Select";
})(Operator1 || (Operator1 = {}));
;
var opt1 = Operator1.Add;                               // opt1的值为0。取枚举项的默认值。
var Operator2;
(function (Operator2) {
    Operator2[Operator2["Add"] = 1] = "Add";
    Operator2[Operator2["Update"] = 2] = "Update";
    Operator2[Operator2["Delete"] = 3] = "Delete";
    Operator2[Operator2["Select"] = 4] = "Select";
})(Operator2 || (Operator2 = {}));
;
var opt2 = Operator2.Update;                            // opt2的值为2。当某一项设置了值后，后续项的值都顺次加1。
var opt2Name = Operator2[2];                            // opt2Name的值为Update。通过值索引可以得到枚举项的名称。
// Any
var obj = 'This is a string.';
obj = 1;
obj = [1, 2];
obj = false;
obj = {};
obj = function () { return false; };
// 强制类型转换
var obj1 = 'This is a string.';
var len = obj1.length;
len = obj1.length;
```

###方法

#####一、方法标准声明和使用

```javascript
 // 方法声明
 function func(x: number, y: number): number {
     return x + y;
 }
```
在TypeScript里，方法声明可以明确定义每一个参数的类型，和返回值的类型。在编译时，编译器会检查方法体的返回值类型是否符合定义的类型，同时在调用的时候也会检查传入的参数类型是否符合定义的类型，参数个数是否符合定义的个数。
```javascript
let result1 = func(1, 2);                     // 正确的调用方式。
let result2 = func_lambda(1, 2, 3);           // 错误的调用方式。参数个数多余定义。
let result3 = func_lambda(1);                 // 错误的调用方式。参数个数少于定义。
let result4 = func_lambda('1', '2');          // 错误的调用方式。参数类型不符合定义。
```
方法声明也支持使用Lambda表达式。
```javascript
 // lambda表达式声明
 let func_lambda: (x: number, y: number) => number = function (x, y) { return x + y };
```
#####二、缺省参数声明
TypeScript也支持缺省参数的声明方式。
```javascript
// 缺省参数定义
let showName = function (firstName: string, lastName?: string): string {
    if (lastName) {
        return firstName + ' ' + lastName;
    } else {
        return firstName;
    }
};

let wholeName1 = showName('小亮', 'Xiaoliang');
let wholeName2 = showName('小亮');
```
通过在参数名称后面加上?，标识该参数是缺省的，调用时如果对应参数位置不传入，对应参数位置则为undefined。

#####三、默认值参数声明
```javascript
// 默认值参数定义
let showName2 = function (firstName: string, lastName = 'Lee'): string {
     return firstName + ' ' + lastName;
 };
 
 let wholeName3 = showName2('小亮');
 ```
 通过在参数名称后加上=号并赋值，标识该参数具有默认值。调用时如果对应参数位置不传入或者传入undefined，则取默认值，否则取对应位置传入的值。

 #####四、多参数声明
```javascript
// 默认值参数定义
 // 多参数定义
 let restParamsFunc = function (param1: string, ...restParams: string[]): string {
     return param1 + ' ' + restParams.join(' ');
 };
 let resParamsFuncResult = restParamsFunc('a', 'b', 'c');
 ```
通过在参入名称前加上...(三个小数点)，标识对应位置的参数可以传入多个。因为参数类型已明确定义，所以传入的多个参数的类型必须与定义保持一致，否则编译时将提示错误。

 #####五、其他类型参数声明
 #####对象类型：
```javascript
// 对象类型参数
let jsonParamFunc = function (x: { p1: string }): string {
    return x.p1;
};

let jsonParamFuncResult1 = jsonParamFunc({ p1: 'a' });              // 赋值类型正确
let jsonParamFuncResult2 = jsonParamFunc({ p1: 'a', p2: 'b' });     // 赋值类型错误，参数属性比定义的多。
let jsonParamFuncResult3 = jsonParamFunc({ p3: 'c' });              // 复制类型错误，参数属性名不匹配。
let params = { p1: 'a', p2: 'b' };
let jsonParamFuncResult4 = jsonParamFunc(params);                   // 用变量代替直接复制，编译器检查通过。
 ```

 #####方法类型：
```javascript
// 方法类型参数
let funcParamFunc = function (func: (x: string, y: string) => string): string {
    let _x = 'a';
    let _y = 'b';
    return func(_x, _y);
};

let funParamFuncResult = funcParamFunc(function (x, y) { return x + y });
 ```
方法参数类型可定义为一个固定结构的方法，该方法就成为了一个回调方法。

 #####六、方法重载
```javascript
// 方法重载
function overloadFunc(x: { p1: string }): string;
function overloadFunc(x: number): number;
function overloadFunc(x): any {
    if (typeof x == 'object') {
        return x.p1;
    }

    if (typeof x == 'number') {
        return x;
    }
}

let overloadFuncResult1 = overloadFunc({ p1: 'a' });
let overloadFuncResult2 = overloadFunc(1);
 ```