1.前言
TypeScript是JavaScript的超集。既然是超集,TypeScript保留了JavaScript所有的语言特性,强类型和class是TypeScript的两大特点。如果对Java有所了解的话,Java的class语法和TypeScript有点相似。据说Vue3.0将用TypeScript重写,相信TypeScript会成为越来越重要,越来越多的前端工程师需要学习TypeScript。那就根据TypeScript官方文档来重点学习一下。
2.安装
> npm install -g typescript
全局安装TypeScript,安装完毕后可以用tsc -v
来查看当前TypeScript版本。
TypeScript文件以后缀名.ts结尾,新建hello.ts文件,写入一下代码。
function welcome(name : string) {
return 'hello' + name;
}
welcome('Jacano');
保存后再终端输入tsc hello.ts
可以看到目录中多了一个hello.js
的文件,刚才的命令就是将typescript转化成javascript。
3.基础类型
typescript是强类型语言,声明变量需要输入变量的类型,typescript中有以下几种变量类型
布尔值
let isDone: boolean = false;
数字
let decLiteral: number = 6; //所有数字均为浮点型
字符串
let name: string = "bob";
数组
let list: number[] = [1, 2, 3];
元组 Tuple
let x: [string, number] = ["s", 10]; // 需要已知数组数量和类型,值要一一对应
枚举
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green; // 用enum关键字声明枚举,默认从0开始编号,可手动改变
Any
Any可代表任意一个类型,有了这个类型,我们可以声明不同类型的数组
let list: any[] = [1, true, "free"];
Void
表示没有任何类型,比如一个函数没有返回值,就用void表示
除此之外,还有Null 和 Undefined、Never、Object等类型
类型断言
你比编译器更明确的知道某个变量的类型的时候,可以使用类型断言,有两种方式
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
另一个语法:
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
一般情况下,我们用第二种的类型断言居多,它还可以在JSX中使用。
4.变量声明
ES6之前,声明变量用var关键字,但是用var关键字声明变量饱受人们诟病,有许多的问题:
- 只有函数作用域和全局作用域,没有块级作用域
- 声明的变量都是全局变量,污染全局命名空间
- 同一个变量可以用var声明两次
- 在for循环中用var声明的下标变量只会是最大数
在ES6引入了let和const两个关键字,用let声明变量有了块级作用域,对同一个变量不能重复声明,在for循环中的打印输出符合常理。因此,用let和const关键字声明变量更符合人们对代码的理解和常规。
5.接口
接口定义:
interface LabelledValue {
label: string;
}
可以理解成一个变量属于 LabelledValue 这个类型,就必须要有 label 这个属性。
当然属性也可以可选
interface SquareConfig {
color?: string;
width?: number;
}
也有只读属性:
interface Point {
readonly x: number;
readonly y: number;
}
6.类
在typescript我们可以愉快的使用类进行面向对象编程了!
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
一个类中有一个属性,一个构造函数和一个方法,最后我们通过new创建了一个对象,这是典型的面向对象编程。
有了类,自然就可以继承,子类继承了父类,那就表明子类拥有了父类公开的属性和方法。
class Animal {
move(distanceInMeters: number = 0) {
console.log(`Animal moved ${distanceInMeters}m.`);
}
}
class Dog extends Animal {
bark() {
console.log('Woof! Woof!');
}
}
const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();
我们可以用修饰符来修饰类中的属性和方法,默认为public,也就是公开的,可以自由的访问。
private可以理解成这个属性或者方法是这个类中私有的,只能在类中访问,子类也访问不了。
protected可以理解成这个属性或者方法是受保护的,只能在类中或者子类中访问,可见,private比protected更封闭。
7.函数
完整的函数类型
let myAdd: (baseValue: number, increment: number) => number =
function(x: number, y: number): number { return x + y; }; // 不必在意参数名是否一致
设置可选参数和默认参数
function buildName(firstName?: string, lastName = "Smith") {
return firstName + " " + lastName;
}
let result1 = buildName("Bob"); // works correctly now, returns "Bob Smith"
let result2 = buildName("Bob", undefined); // still works, also returns "Bob Smith"
let result3 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
let result4 = buildName("Bob", "Adams"); // ah, just right
?代表这个参数可选,在参数后赋值表示默认值