Typescript实践总结[基础+工程+实践]
# 第一章 基础篇
TS基础篇

# 一、基本类型
JavaScript的类型分为两种:原始数据类型和对象类型。- 原始数据类型包括:布尔值、数值、字符串、
null、undefined以及 ES6 中的新类型Symbol - 本节主要介绍前五种原始数据类型在
TypeScript中的应用。 - 布尔值是最基础的数据类型,在
TypeScript中,使用boolean定义布尔值类型
ES6数据类型
BooleanNumberStringArrayFunctionObjectSymbolundefinednull
Typescript数据类型
BooleanNumberStringArrayFunctionObjectSymbolundefinednullvoidanynever- 元组
- 枚举
- 高级类型
正确的写法
➖➖➖➖➖➖➖➖➖布尔➖➖➖➖➖➖➖➖➖
// 布尔值
let isDone: boolean = false;
// 事实上 `new Boolean()` 返回的是一个 `Boolean` 对象
let createdByNewBoolean: Boolean = new Boolean(1);
//(直接调用 `Boolean` 也可以返回一个 `boolean` 类型)
let createdByBoolean: boolean = Boolean(1);
➖➖➖➖➖➖➖➖➖数值➖➖➖➖➖➖➖➖➖
// 数值
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
// ES6 中的二进制表示法
let binaryLiteral: number = 0b1010;
// ES6 中的八进制表示法
let octalLiteral: number = 0o744;
let notANumber: number = NaN;
let infinityNumber: number = Infinity;
➖➖➖➖➖➖➖➖➖字符串➖➖➖➖➖➖➖➖➖
let myName: string = 'Tom';
➖➖➖➖➖➖➖➖➖空值➖➖➖➖➖➖➖➖➖
// 没有返回值的函数为void
function alertName(): void {
alert('My name is Tom');
}
//声明一个 void 类型的只能将它赋值为 undefined 和 null
let unusable: void = undefined;
➖➖➖➖➖➖➖➖➖Null 和 Undefined➖➖➖➖➖➖➖➖➖
// undefined 类型的变量只能被赋值为 undefined,null 类型的变量只能被赋值为 null
let u: undefined = undefined;
let n: null = null;
@前端进阶之旅: 代码已经复制到剪贴板
错误的写法
注意:正确的很好记,大多数人都会写正确的,关键是要记住这些错误的!!!
➖➖➖➖➖➖➖➖➖布尔➖➖➖➖➖➖➖➖➖
// 注意,使用构造函数 `Boolean` 创造的对象不是布尔值
let createdByNewBoolean: boolean = new Boolean(1);❌
➖➖➖➖➖➖➖➖➖数值➖➖➖➖➖➖➖➖➖
let decLiteral: number = "6";❌
➖➖➖➖➖➖➖➖➖字符串➖➖➖➖➖➖➖➖➖
let myName: string = 999;❌
➖➖➖➖➖➖➖➖➖空值➖➖➖➖➖➖➖➖➖
// 没有返回值的函数为void
function alertName(): void {❌
return 666;
}
//声明一个 void 类型的只能将它赋值为 undefined 和 null
let unusable: void = 'I love you';❌
➖➖➖➖➖➖➖➖➖Null 和 Undefined➖➖➖➖➖➖➖➖➖
// undefined 类型的变量只能被赋值为 undefined,null 类型的变量只能被赋值为 null
let u: undefined = 888;❌
let n: null = 999;❌
@前端进阶之旅: 代码已经复制到剪贴板
# 二、任意值
正确的写法
// 顾名思义,可以被任何值赋值
let anyThing: any = 'hello';
let anyThing: any = 888;
let anyThing: any = true;
let anyThing: any = null;
let anyThing: any = undefined;
// 变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型:
let any;
any =true;
@前端进阶之旅: 代码已经复制到剪贴板
# 三、类型推论
正确的写法
// 如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。
let myFavoriteNumber = 'seven';
//等价于
let myFavoriteNumber :string= 'seven';
@前端进阶之旅: 代码已经复制到剪贴板
错误的写法
// 第一句已经被推论为String类型了
let myFavoriteNumber = 'seven';
myFavoriteNumber = 7;❌
@前端进阶之旅: 代码已经复制到剪贴板
# 四、联合类型
正确的写法
// 联合类型(Union Types)表示取值可以为多种类型中的一种。
// 当你允许某个变量被赋值多种类型的时候,使用联合类型,管道符进行连接
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
// 也可用于方法的参数定义, 都有toString方法,访问 string 和 number 的共有属性是没问题的
function getString(something: string | number): string {
return something.toString();
}
@前端进阶之旅: 代码已经复制到剪贴板
错误的写法
// number类型没有length属性.所以编译错误,因为我们只能访问此联合类型的所有类型里共有的属性或方法:
function getLength(something: string | number): number {❌
return something.length;
}
@前端进阶之旅: 代码已经复制到剪贴板
# 五、对象的类型——接口
正确的写法
// 赋值的时候,变量的形状必须和接口的形状保持一致(不能多也不能少,类型还必须一致)
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25
};
IUserInfo{
age : any;//定义一个任何变量的 age.
userName :string;//定义一个 username.
}
function getUserInfo(user : IUserInfo):string{
return user.age+"======"+user.userName;
}
➖➖➖➖➖➖➖➖➖可选属性➖➖➖➖➖➖➖➖➖
interface Person {
name: string;
age?: number; // 表示这个属性可有可无
}
let tom: Person = {
name: 'Tom'
};
// 可索引签名
interface StringArrary {
[index]: string // 数字索引。通过数字索引,返回string类型
[string]: string // 字符串索引签名。两者不能混用,一起使用的前提是数字索引是字符串索引的子集
}
let myArr: StringArrary
myArr = ['test1','test2']
let myString = myArr[0]
➖➖➖➖➖➖➖➖➖任意属性➖➖➖➖➖➖➖➖➖
//希望一个接口允许有任意的属性,可以使用如下方式:旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
interface Person {
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
name: 'Tom',
gender: 'male' // 可以加其他的属性
};
➖➖➖➖➖➖➖➖➖只读属性➖➖➖➖➖➖➖➖➖
interface Person {
readonly id: number; //
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
id: 89757, // 只读
name: 'Tom',
gender: 'male'
};
@前端进阶之旅: 代码已经复制到剪贴板
错误的写法
// 一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
interface Person {
name: string;
age?: number;
[propName: string]: string;
}
let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'❌
};
上例中,任意属性的值允许是 string,但是可选属性 age 的值却是 number,number 不是 string 的子属性,所以报错了。
➖➖➖➖➖➖➖➖➖只读属性➖➖➖➖➖➖➖➖➖
interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
name: 'Tom',
gender: 'male'
};
tom.id = 89757; // 不能被二次赋值❌
@前端进阶之旅: 代码已经复制到剪贴板
数组只读属性
let myARr:readonlyArrary<number> = [1,2,3]
@前端进阶之旅: 代码已经复制到剪贴板
# 六、数组的类型
正确的做法
let fibonacci: number[] = [1, 1, 2, 3, 5];
let fibonacci: Array<number> = [1, 1, 2, 3, 5];
➖➖➖➖➖➖➖➖➖用接口表示数组➖➖➖➖➖➖➖➖➖
interface NumberArray {
[index: number]: number;
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];
➖➖➖➖➖➖➖➖➖any 在数组中的应用➖➖➖➖➖➖➖➖➖
let list: any[] = ['Xcat Liu', 25, { website: 'http://xcatliu.com' }];
➖➖➖➖➖➖➖➖➖类数组➖➖➖➖➖➖➖➖➖
function sum() {
let args: IArguments = arguments;
}
@前端进阶之旅: 代码已经复制到剪贴板
错误的做法
# 七、函数的类型
正确的做法
错误的做法
# 7.1 函数相关知识点梳理
四种声明方式:
- 通过
function - 通过变量
- 通过接口
- 通过类型别名
用interface定义函数和用type定义函数有区别?
函数重载
函数名相同,返回类型不同
# 八、类型断言
正确的做法
类型约束