什么是TypeScript
TrpeScript是JavaScript的一个强类型体现,是JavaScript的一个超集,弥补了JavaScript的一些短板(JavaScript没有提供类和模块的概念)。它由Microsoft开发,GitHub地址
TypeScript的优势
- TypeScript定义了一套类型机制来保证编译时的强类型的判断
- TypeScript很包容,.js文件可直接命名为.ts
- 语法提示精准,在编译阶段就能发现大部分错误
- 兼容性好,即使第三方库不是用TypeScript写的也可以提供单独的类型文件供TypeScript读取
- 模块化,利用TypeScript的关键字module,可以达到类似于命名空间的效果,而export可以控制是否被外部访问
注:- module可以嵌套,访问时用 . 作分隔符
- 只有带关键字 export的才能被外部访问
- module 可以合并,但是非 export 的对象在其他 module 下,即使是同一名称也不能被访问。
TypeScript的缺点
- 一点的学习成本,需要理解接口(interfaces)、泛型(Generics)、类(classes)、枚举类型(Enums)等概念
- 前期工作量较大,但后期维护方便
- 与一些库结合不会很完美
安装TypeScript
npm install -g typescript
编译文件
tsc hello.ts
我们约定使用TypeScript 编写文件以 .ts 为后缀,用Typescript 编写React时,以 .tsx 为后缀。
原始数据类型
JavaScript的类型分为两种:原始数据类型(Primitive data types)和对象类型(Object types)
原始数据类型包含:布尔(boolean),数值(number),字符串(string),null,undefined,Symbol.
对象类型:对象(Object)
let show : boolean = false; //Boolean类型,编译通过
let cont : boolean = 0; //number类型,编译失败
let float : number = 0.001; // 浮点数
let float : any= "hello word"; // any 可以是任何类型
Enum 枚举
enum color {red = 1,green = 2,black = 3};
let r:color=color.red
console.log(r);//默认从0开始,这里会输出0
let r:color=color[2]
console.log(r);//green
空值 void
javaScript中没有空值(void)的概念,在TypeScript中,可以用 void 表示没有任何返回值的函数
function alertName():void {
alert("空值");
}
声明一个 void 类型的变量没什么用,因为你只能将它赋值为 null 和 undefined
let unsum:void = undefined;
类型别名
类型别名用来给一个类型起一个新名字 ,可以使用 type 创建类型别名
type Name = string;
type Name =() => string;
type NameReslover = Name | lover;
function getName(n: NameResolver): Name {
if (typeof n === 'string') {
return n;
} else {
return n();
}
}
联合类型
联合类型(Union Types ) 表示取值可以为多种类型中的一种。
let nav:string | number
nav = "seven";
nav = 7;
字符串字面量类型
字符串字面量类型用来约束取值只能是某几个字符串中的一个,字符串字面量类型都是使用 type 进行定义。
type EventNames = 'click' | 'scroll' | 'mousemove';
function handleEvent(ele: Element, event: EventNames) {
// do something
}
handleEvent(document.getElementById('hello'), 'scroll'); // 没问题
handleEvent(document.getElementById('world'), 'dblclick'); // 报错,event 不能为 'dblclick'
对象类型 - 接口
** 什么是接口 **
在面对对象语言中,接口(interfaces)是一个和重要的概念,他是对行为的抽象,而具体实现则由类(classes)去实现(implement)
基础
interface Person (){
readonly id :number
name:string;
age?:number;
[propName: string]: any;
};
let tom:Person ={
name: 'Tom';
age : 18
};
注释:
- 接口一般首字母大写
- 定义的变量和接口属性保持一致,多,少都不行
- 可选属性在定义属性的时间在属性后跟 ?
- 使用 [proName:string]定义了任意属性取 string 类型的值,需要注意的是,那么需要确定的和可选的类型都必须是它的类型的子集(在此age就会报错,因为任意属性取得是string,而age是number,在这里我们可以用联合属性 string | number)
- 只读属性 readonly
数组的类型
基础操作
let numList :number[ ] = [1,2,3,4,5]
注释:
1. 数据规定类型为 ** number** 则不允许出现其他类型
** 用接口表示数组 **
interface NumArray {
[index:number]:number;
}
let array:NumberArray = [1,1,2,3,4,5]
元组
// 定义一一个元组
let tom: [string,number] = ['tom',25];
//当赋值或者访问的时间
let tom: [string ,number];
tom[0] = 'Tom';
tom[1] = 25;
//也可以赋值其中一项
let tom: [string ,number];
tom[0] = 'tom'
函数的类型
在JavaScript中,有两种长见的定义函数的方式 – 函数声明 和 函数表达式
//函数声明
function sun (x,y) {
return x + y;
}
// 函数表达式
let Sum = function (x,y) {
return x + y;
}
而TypeScript要在中对其约束,也就是规定类型
//函数声明
function sun (x:number,y:number) :number{
return x + y;
}
注释:
1. 参数对照,多,少都会报错
2. 可选参数 ?
3. 默认参数
4. 剩余参数
声明文件
- declare var 声明全局变量
- declare function 声明全局方法
- declare class 声明全局类
- declare enum 声明全局枚举类型
- declare namespace 声明(含有子属性的)全局对象
- interface 和 type 声明全局类型
- export 导出变量
- export namespace 导出(含有子属性的)对象
- export default ES6 默认导出
- export = commonjs 导出模块
- export as namespace UMD 库声明全局变量
- declare global 扩展全局变量
- declare module 扩展模块
- /// 三斜线指令
什么是声明文件
通常我们会把声明文件语句放到一个单独的文件(jQuery.d.ts)中,这就是声明文件
声明文件必需以 .d.ts 为后缀。
声明合并
函数的合并
可以使用重载定义多个函数类型
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
接口的合并
interface Alarm {
price: number;
}
interface Alarm {
weight: number;
}
// 相当于
interface Alarm {
price: number;
weight: number;
}
备注:合并的属性类型必须是一致的,否则会报错。
类
类的概念
- 类(Class):定义了一件事物的抽象特点,包含它的属性和方法
- 对象(Object):类的实例,通过 new 生成
- 面向对象(OOP)的三大特性:封装、继承、多态
- 封装(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象,同时也保证了外界无法任意更改对象内部的数据
- 继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
- 多态(Polymorphism):由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。比如 Cat 和 Dog 都继承自 Animal,但是分别实现了自己的 eat 方法。此时针对某一个实例,我们无需了解它是 Cat 还是 Dog,就可以直接调用 eat 方法,程序会自动判断出来应该如何执行 eat
- 存取器(getter & setter):用以改变属性的读取和赋值行为
- 修饰符(Modifiers):修饰符是一些关键字,用于限定成员或类型的性质。比如 public 表示公有属性或方法
- 抽象类(Abstract Class):抽象类是供其他类继承的基类,抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现
- 接口(Interfaces):不同类之间公有的属性或方法,可以抽象成一个接口。接口可以被类实现(implements)。一个类只能继承自另一个类,但是可以实现多个接口