TypeScript 入门

学习 TypeScript 的优势

  • 支持 ES6 规范
  • 强大的 IDE 支持:WebStorm
  • Angular 2~4 的开发语言

安装 TypeScript 的开发环境

  • 什么是 compiler?
    • 编译器
  • 为什么需要 compiler?
    • 需要将 TypeScript 转化为 JavaScript 运行
  • TypeScript 在线 compiler
  • TypeScript 本地 compiler
    • npm install -g typescript
    • tsc –version

TypeScript 概念、语法和特性介绍

字符串新特性

多行字符串

1
2
3
4
5
6
7
// TypeScript
var string = `aaa
bbb
ccc`;
// JavaScript
var string = "aaa\n"+"bbb\n"+"ccc\n";

字符串模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// TypeScript
var name = "LuisEdware";
var getName = function(){
return "LuisEdware";
}
console.log(`Hello ${name}`);
console.log(`Hello ${getName()}`);
console.log(`<div>
<span>${name}</span>
<span>${getName()}</span>
</div>
`);
// JavaScript
var name = "LuisEdware";
var getName = function () {
return "LuisEdware";
};
console.log("Hello " + name);
console.log("Hello " + getName());
console.log("<div>\n<span>" + name + "</span>\n<span>" + getName() + "</span>\n</div>\n");

自动拆分字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// TypeScript
function test(template, name, age) {
console.log(template);
console.log(name);
console.log(age);
}
var name = "AnnEason";
var getAge = "";
test`hello my name is ${name}, i'm ${getAge}`;
// JavaScript
function test(template, name, age) {
console.log(template);
console.log(name);
console.log(age);
}
var name = "AnnEason";
var getAge = "";
(_a = ["hello my name is ", ", i'm ", ""], _a.raw = ["hello my name is ", ", i'm ", ""], test(_a, name, getAge));
var _a;

参数新特性

参数类型,在参数名称后面使用冒号来指定参数类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var username: string = "Luis Edware";
# 编译报错、JavaScript 执行正常
username = 13;
var age: number = 13;
var man: boolean = true;
function test(name: string): string{
return "";
}
test(username);
# 编译报错,需要提供字符串类型的参数
test(age);

默认参数,在参数声明后面使用等号来指定参数的默认值

1
2
3
4
5
6
7
8
function test(a: string, b: string, c:string = "jojo")
{
console.log(a);
console.log(b);
console.log(c);
}
test('xxx','yyy','zzz');
test('xxx','yyy');

可选参数,在方法的参数声明后面使用问好来标明此参数为可选参数

1
2
3
4
5
6
function test(a: string, b?: string, c:string = 'jojo')
{
console.log(a);
console.log(b.length);
console.log(c);
}

函数新特性

Rest and Spread 操作符,用来声明任意数量的方法参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function func1(...args)
{
args.forEach(function(arg){
console.log(arg);
})
}
func1(1,2,3);
func1(7,8,9,10,11);
function func2(a,b,c){
console.log(a);
console.log(b);
console.log(c);
}
var args = [1,2];
func2(...args);
var args2 = [7,8,9,10,11];
func2(...args2);

generator 函数,控制函数的执行过程,手工暂停和回复代码执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function* getStockPrice(stock){
while(true){
yield Math.random()*100;
}
}
var priceGenerator = getStockPrice("IBM");
var limitPrice = 15;
var price = 100;
while(price > limitPrice){
price = priceGenerator.next().value;
console.log(`the generator return ${price}`);
}
console.log(`buying at ${price}`);

destructuring 析构表达式,通过表达式将对象或数组斋戒成任意数量的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
function getStock(){
return {
code: "IBM",
price: 1000
}
}
// ES5
var stock = getStock();
var code = stock.code;
var price = stock.price;
// TypeScript
var {code,price} = getStock();
console.log(code);
console.log(price);
var {code: codex, price} = getStock();
console.log(codex);
console.log(price);
// TypeScript 获取对象中对象的值
function getStock2(){
return {
code: "IBM",
price: {
price1: 100,
price2: 200
}
}
}
var {code, price: {price2}} = getStock();
console.log(codex);
console.log(price);
// 数组析构表达式
var array1 = [1,2,3,4];
var [number1, number2] = array1;
var [,,number3,number4] = array1;
console.log(number1);
console.log(number2);
console.log(number3);
console.log(number4);
var [number1,number2, ...others] = array1;
console.log(number1);
console.log(number2);
console.log(others);
// 方法析构表达式
var array1 = [1,2,3,4];
function doSomething([number1,number2, ...others]){
console.log(number1);
console.log(number2);
console.log(others);
}
doSomething(array1);

表达式和循环

箭头表达式:用来声明匿名函数,消除传统命名函数的 this 指针问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 一行不要写大括号
var sum = (arg1, arg2) => arg1 + arg2;
// 多行需要写大括号
var sum2 = (arg1, arg2) => {
return arg1 + arg2;
}
// example - 1
var myArray = [1, 2, 3, 4, 5];
console.log(myArray.filter(value => value % 2 == 0));
// example - 2
function getStock(name: string) {
this.name = name;
var that = this;
setInterval(function () {
// this 指向 setInterval 作用域,this.name 无效
console.log("name is :" + that.name);
},1000);
}
var stock1 = new getStock("Hello")
function getStock2(name: string) {
this.name = name;
setInterval(() => {
console.log("name is :" + this.name);
}, 1000);
}
var stock2 = new getStock2("World");

循环,forEach(), for in 和 for of

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var myArray = [1, 2, 3, 4];
myArray.desc = "for number";
// 循环数组,会把 desc 属性忽略掉
myArray.forEach(value => console.log(value));
// 循环 key
for (let key in myArray) {
console.log(key);
}
// 循环 value
for (let value of myArray) {
console.log(value);
}

面向对象特性

类,类是 TypeScript 的核心,使用 TypeScript 开发时,大部分代码都是写在类里面的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Person{
public name;
private fish;
// 构造函数
constructor(public food:string) {
console.log('Hello');
}
// 修饰符
public eat() {
console.log(`My name is ${this.name},I am eating ${this.food}.`);
}
}
var p1 = new Person("egg");
p1.name = "Luis Edware";
p1.eat();
// 继承
class Employee extends Person{
public code: string;
public constructor(public food: string, code:string) {
super(food);
this.code = code;
}
public work() {
super.eat();
this.doWork();
}
private doWork() {
console.log(`I am Working with ${this.code}`);
}
}
var e1 = new Employee("apple", "Hello World");
e1.name = "Ann Eason";
e1.work();

泛型,参数化的类型,一般用来限制集合的内容

1
2
3
4
5
var workers: Array<Person> = [];
workers[0] = new Person("zhangsan");
workers[1] = new Employee("lisi", "hell world");
// 报错,只能放入对象为 Person 类型的数据
workers[2] = 3;

接口,用来建立某种代码约定,使得其它开发者在调用某个方法或创建新的类时必须遵循接口所定义的代码约定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
interface IPerson{
name: string;
age: number;
}
class Person{
constructor(public config: IPerson) {
}
}
var p1 = new Person({ name: "hello", age: 123 });
interface Animal{
eat();
}
// 实现接口,必须实现它所声明的函数
class Sheep implements Animal {
eat() {
console.log("I am eating something");
}
}

模块,模块可以帮助开发者将代码分割为可重用的单元。开发者可以自己决定将模块中的哪些资源(类、方法、变量)暴露出去供外部使用,哪些资源只在模块内使用。在 TypeScript 中,一个文件就是一个模块。export 和 import 关键字支撑模块的使用。export 对外暴露,import 对内导入。

1
2
3
4
5
export class Person{
}
import {Person} from './person.tc';

注解,注解为程序的元素(类,方法,变量)加上更直观更明了的说明,这些说明信息与程序的业务逻辑无关,而是供指定的工具或框架使用的。

1
2
3
4
5
6
7
8
9
10
11
12
import {Component} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
// 当实例化 AppComponent 的时候,Angular 框架应该去加载 templateUrl 属性所指的页面和 styleUrls 属性所指的层叠样式表。
export class AppComponent {
title = 'app works!';
}

类型定义文件(*.d.ts),用来帮助开发者在 TypeScript 中使用已有的 JavaScript 的工具包,如:jQuery,常用的类型文件可以从 Github 项目的 DefinitelyTyped/DefinitelyTyped 获取。或者使用工具 typings/typings。