一、安装环境并run起来
-
npm安装typescript
npm install -g typescript
-
typescript和node都必须装好,然后在任意目录创建一个hello.ts, typescript是以ts结尾的。创建好了用编辑器(sublime、vscode、webstorm)打开hello.ts,写入代码:
console.log('hello world');
-
打开terminal,在当前目录执行命令 :
tsc hello.ts
-
执行完上面命令后,ts会转成js,会在当前目录生成一个hello.js,然后在terminal执行如下命令,会看到终端输出了hello world
node hello.js
二、数据类型
-
字符串
let str: string = 'Harry';
-
数值
let age: number = 27;
-
布尔值
let isTrue: boolean = true;
-
null
let n: null = null;
-
undefined
let u: undefined = undefined;
三、类型推论
-
对比介绍类型推论:
let a = 'Harry'; a = 27; //error,上一行已经被解析成了string类型的了,所以会报错,Type 'number' is not assignable to type 'string'. console.log(a); let a; // 如果不赋值,就是any类型,所以下面对a赋任何类型的值都不会出错 a = 'Harry'; a = 27; console.log(a); // 打印出来27
-
类型别名,用type声明
type Name = string; function test(param: Name): Name { return param; } console.log(test('2222')); // 2222
四、联合类型
-
联合类型使用 | 分隔每个类型,允许 变量c 的类型是 string 或者 number,但是不能是其它类型,如果是其它类型就会error
// 联合类型 let c : number | string; c = 'aa'; console.log(c.length); // 2 console.log(c.toString());// aa c = 7; console.log(c.toString()); // 打印7, 这儿不会报错,因为toString()是number和string的共有属性 console.log(c.length); // c是number类型的,没有length属性,所以报错 Property 'length' does not exist on type 'number'.
五、接口
-
定义的变量me必须和接口interface的属性一一对应,不能增加或者删除,如下:
interface Person { name: string; age: number; } let me: Person = { name: 'Harry', age: 27 };
-
可选属性的话就不需要一一对应了,如下:
interface Person { name: string; age?: number; } let me: Person = { name: 'Harry', };
六、数组
-
数组定义,如下:里面存放的都是number类型,不可以存放除了number之外的类型
let array: number[] = [1, 1, 2, 3, 5]; let array1: number[] = [1, '1', 2, 3, 5]; // error Type 'string' is not assignable to type 'number'.
-
这样写可以向数组内添加任意类型
let array2: Array<any> = [1, 1, 2, 3, 5]; array2.push('aaa'); console.log(array2);
-
接口表示数组
interface MyArray { [index: number]: number; } let fibonacci: MyArray = [1, 1, 2, 3, 5];
七、函数
-
函数声明: x和y是入参 ,冒号后面是返回值的类型
function sum(x, y): number { return x + y; } let result = sum(x: 3, y: 4); console.log(result); // 7
-
带可选参数的函数声明,lastName可传可不传
function fetchName(firstName: string, lastName?: string): string { if (lastName) { return firstName + '' + lastName; } else { return firstName; } } let res = fetchName(firstName: 'Ha', lastName: 'rry'); console.log(res); // Harry let res1 = fetchName(firstName: 'Ha'); console.log(res1); // Ha
-
带默认值参数的函数
function fetchName(firstName: string, lastName: string = 'rry'): string { return firstName + '' + lastName; } let res = fetchName(firstName: 'Ha'); console.log(res); // Harry
-
剩余参数
function pushData(array: any[], ...items: any[]) { items.forEach(function (item) { array.push(item); }) } let aa: any[] = [1, 2]; push(aa, 3, 4, 5); console.log(aa); // 1 2 3 4 5
-
函数的重载,重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。比如,我们需要实现一个函数 reverse,输入数字 123 的时候,输出反转的数字 321,输入字符串 'hello' 的时候,输出反转的字符串 'olleh'。
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(''); } }
八、元组
-
定义一对值分别为 string 和 number 的元组:
let tup: [string, number] = ['Harry', 27]; // console.log(tup[0]); // Harry console.log(tup[1]); // 27 tup[0] = 'haha'; tup[0] = '18'; console.log(tup[0]); // haha console.log(tup[1]); // 18
-
注意事项
let tup: [string, number]; // 如果这样声明后面不能对它进行赋值,否则error tup[0] = 'Harry'; // error console.log(tup[0]); let tup: [string, number] = []; // 这样声明后面能对他赋值 tup[0] = 'Harry'; tup[1] = 27; console.log(tup[0]); // Harry let tup: [string, number] = ['Harry', 27]; console.log(tup[2]); // 角标越界
九、枚举
-
基本的枚举声明
enum Num {A, B, C, D, E, F, G}; console.log(Num["A"] === 0); // true console.log(Num[0] === "A"); // true
-
常数枚举
const enum Num {A, B, C, D, E, F, G}; console.log(Num["A"] === 0); // true console.log(Num[0] === "A"); // error 因为使用const声明的enum,无法修改
-
外部枚举
declare const enum Num {A, B, C, D, E, F, G}; console.log(Num.A); // 0
十、类
-
类的介绍
-
类(Class):定义了一件事物的抽象特点,包含它的属性和方法
-
对象(Object):类的实例,通过 new 生成
-
面向对象(OOP)的三大特性:封装、继承、多态
-
封装(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象,同时也保证了外界无法任意更改对象内部的数据
-
继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
-
多态(Polymorphism):由继承而产生了相关的不同的类,对同一个方法可以有不同的响应
-
存取器(getter & setter):用以改变属性的读取和赋值行为
-
修饰符(Modifiers):修饰符是一些关键字,用于限定成员或类型的性质
-
抽象类(Abstract Class):抽象类是供其他类继承的基类,抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现
-
接口(Interfaces):不同类之间公有的属性或方法,可以抽象成一个接口。接口可以被类实现(implements)。一个类只能继承自另一个类,但是可以实现多个接口
-
-
写一个简单类。name属于全局变量,不能用let 、var修饰,局部变量可以用let、var修饰
class Person { public name; // 存取值 含有get set方法 static age; // 静态属性,直接通过类来访问 constructor(name) { // 构造器 this.name = name; } say() { return `My name is ${this.name}`; } } let a = new Person('Harry'); console.log(a.say()); // My name is Harry Person.age = 27; console.log(Person.age); // 27
-
继承
class Dog extends Person { constructor(name) { super(name); // 调用父类的 constructor(name) console.log(this.name); } say() { return 'Meow, ' + super.say(); // 调用父类的 say() } } let c = new Dog('Jack'); console.log(c.say()); // Meow, My name is Harry
-
抽象类,抽象类不允许直接实例化 必须有子类继承自它
abstract class Person { name; constructor(name) { this.name = name; } say() { console.log('My name is ${this.name}'); } } class Dog extends Person { say() { console.log(`My name is Dog ${this.name}`); } } let = new Person(); //Cannot create an instance of an abstract class. let d = new Dog('Tom'); d.say(); // My name is Dog Tom
十一、类与接口
-
一个类只能继承自另一个类,有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements 关键字来实现。这个特性大大提高了面向对象的灵活性
interface Animal { eat(); } interface Animals { run(); } class Dog implements Animal { eat() { console.log('Dog eat'); } } class Cat implements Animal, Animals { // 一个类可以实现多个接口: eat() { console.log('Cat eat'); } run() { console.log('Cat run'); } } let d = new Dog(); d.eat(); let c = new Cat(); c.eat(); c.run();
-
接口可以继承接口
interface Animals { run(); } interface Person extends Animals{ speak(); } class Tom implements Person { speak() { console.log('Tom speak'); } run() { console.log('Tom run'); } } let t = new Tom(); t.speak(); t.run();
十二、泛型
-
在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。如下代码:数组中每一项都应该是输入的 value 的类型,而非any类型
function arrayOperation<T>(length: number, value: T): Array<T> { let result: T[] = []; for (let i = 0; i < length; i++) { result[i] = value; } return result; } let aaa = arrayOperation<string>(10, 'O'); console.log(aaa); // [ 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O' ]