TypeScript和JavaScript
TypeScript 是JavaScript 的一个超集,支持ES6标准
TypeScript的实际目标是开发大型应用,他可以编译成纯的JavaScript
TypeScript增加的功能有:
- 类型批注和编译时类型检查
- 类型推断
- 接口
- 枚举
- Mixin
- 泛型编程
- 名字空间
- 元组
- Await
从ES6反移植来的:类、模块、lambda函数的箭头语法、可选参数和默认参数
TypeScript安装
如果你想让自己的TS代码转化成JS代码,可以通过NPM来进行安装
//全局安装typescript工具
npm install -g typescript
//将ts文件生成一个同名的js文件,放在同一目录下
tec test.ts
另外一种方法就是使用IDE,比如VSCode
TypeScript的基础语法
TS(TypeScript的简写)程序由模块、函数、变量、语句和表达式、注释等组成
TypeScript的一些语法特性
- 保留字: in break if try continue implements等等
- TS会忽略程序中出现的空格、制表符和换行符
- TS区分大小写
- 分号可选,但尽量不省略
- TS注释:// 行注释 / 块注释 /
- TS是面向对象的,如下边的例子1234567class Site{name(): void{console.log("Me");}}var obj = new Site();obj.name();
TypeScript的基础类型
数据类型 | 关键字 | 描述 |
---|---|---|
任意类型 | any | 声明为any的变量可以赋予任意类型的值 |
数字类型 | number | 双精度64为浮点数 |
字符串类型 | string | 使用’或者”来表示,反引号`来定义多行字符串和内嵌表达式 |
布尔类型 | boolean | true或false |
数组类型 | 无 | let arr: number[] |
元组 | 无 | let x: [string, number] |
枚举 | enum | 枚举类型用于定义数值集合 |
void | void | 用于表示方法返回值的类型,表示该方法没有返回值 |
null | null | 表示对象值缺失 |
undefined | undefined | 初始化变量为一个未定义的值 |
never | never | never是其他类型包括null和undefined |
这里着重说一下TS的``多行字符串,他还可以作为字符串模板使用,和对字符串模板进行拆分
多行字符串
1234var str = `aaabbbccc`;对应JS的var str = "aaa\nbbb\nccc";字符串模板:
12var name = "myName";console.log(`my name is ${name}`);字符串模板拆分
123456789101112function test(templete, name, age){console.log(templete);console.log(name);console.log(age);}var myName = "Guoruiyang";var getAge = function(){return 18;}test`hello my name is ${myName}, i'm ${getAge()}`//注意这里的test后没有()
TypeScript的变量声明
TS的变量的声明只是多了类型声明,其他同JS一样。如:
TypeScript的运算符
TS的运算符、条件语句、循环、Number、String、Array同JS无区别
TypeScript的函数
TS的函数参数与JS不同
传入函数的参数可以指定类型
123var getAge(num: number){return num;}传入函数的参数可以指定默认值
123456789101112// 带默认值的参数放在必选参数的的后边function test(a:string, b:string, c:string = "jojo"){console.log(a);console.log(b);console.log(c);}//输出xx\n yy\n zztest("xx", "yy", "zz");//输出xx\n yy\n jojotest("xx", "yy");//报错test("xx");可选参数
123456789101112//第二个参数是可选的,可选参数放在必选参数的的后边function test(a:string, b?:string, c:string = "jojo"){console.log(a);console.log(b);console.log(c);}//输出xx\n yy\n zztest("xx", "yy", "zz");//输出xx\n yy\n jojotest("xx", "yy");//输出xx\n undefine jojotest("xx");
函数新特性
Rest和Spread操作符 …可以传入函数任意数量的参数
1234567891011121314151617181920function func1(...args){args.forEach(function(arg){console.log(arg);})}var args = [1,2,3];//输出1\n 2\n 3func1(args);function func2(a, b, c){console.log(a);console.log(b);console.log(c);}var args = [1,2];//输出1\n 2\n undefinefunc1(...args);var args1 = [1, 2, 3, 4];//输出1\n 2\n 3\nfunc1(...args1);generator函数 控制函数的执行
generator函数的声明和调用如下:123456789101112//函数后边跟*表示是generator函数function* doThings(){console.log("start");yield;console.log("end");}//doThings不能直接调用var func1 = doThings;//输出startfunc1.next();//输出endfunxc1.next();destructuring析构表达式
通过destructuring表达式将对象或数组拆解成任意数量的变量12345678910111213141516171819202122//返回一个对象function getStock(){return {code: "IBM",price: 100,other: 123}}// 等同于var a = getStock(); a.code="IBM"; a.price=100;var {code, price} = getStock();//错误var {codex, price} = getStock();//正确 codex的值就是code的值var {code: codex, price} = getStock();var array1 = [1, 2, 3, 4, 5];//num1 = 1; num2 = 2var [num1. num2] = array1;//num1 = 3; num2 = 4var [,,num1,num2] = array1;//num1 = 1; args = [2, 3, 4, 5]var [num1, ...args] = array1;箭头表达式
通过=> 箭头表达式来声明匿名函数,消除了传统匿名函数中this指针的问题12345678910111213141516function getSockt(name:string){this.name = name;setInterval(function(){console.log("my name is " + this.name);}, 1000);}function getSockt2(name:string){this.name = name;setInterval(() => {console.log("my name is " + this.name);}, 1000);}//调用getSockt("IBM")函数输出my name isvar stock = new getSockt("IBM");//调用getSockt2("IBM")函数输出my name is IBMvar stock2 = new getSockt2("IBM");
TypeScript元组
在我看来元组解释特殊的数组,元组里的数据类型可以不一样
TypeScript联合类型
联合类型就是给一个变量设置多种类型,通过|管道符来实现
语法格式: Type1|type2|type3
var valu:string|number;
var arr: string[] | number[];
TypeScript接口
学过面向对象的我们都知道接口,接口就是一系列抽象方法的声明
TS的接口定义如下:interface interface_name{ }
- 接口实例,实现接口的属性和方法
- 接口继承, 接口用过其他接口来扩展自己,关键字是extends
单接口:Child_interface_name extends super_interface_name
多接口:Child_interface_name extends super_interface_name, super_interface1_name
TypeScript类
TS的类和其他卖你想对象的语言一样,描述了所创建的对象的公共的属性和方法
定义方式如: class class_name { // 类作用域 }
类的继承:
- 类可以继承其他类,类继承也是使用extends关键字
子类除了不能继承父类的私有成员和构造函数,其他都可以继承。TS一次只能继承一个类,不支持继承多个类。但支持多重继承
class child_name extends parent_name
子类对父类方法的重写叫做方法的重写 - 类可以继承接口,继承接口使用implements关键字
class class_name implements interface_name - 类中属性方法的控制修饰符
static: 指定类的数据成员为静态的,静态成员可以直接通过类名来调用
public: 默认值,☞共有,可以在任何地方被访问
protected: 受保护的,可以在其自身以及其父类和子类访问
private: 私有,只能在其所定义的类访问
TypeScript命名空间、模块、声明文件
TS的命名空间
TS的命名空间可以说是ES6的模块化,通过TS明明空间namespace来定义的代码会编译成基于闭包将局部变量暴露给外部,命名空间最好不要和模块一起混用。如:1234567891011namespace MyMath{//使用namespace 指令来申明命名空间MyMath//使用export指令将属性和方法暴露给域外部export const PI = 3.14;export function sumValue(num1: number, num2: number){return num1 + num2;}}// 在外部使用命名空间MyMath.PI;MyMath.sunValue(2, 3);模块
TS对ES6和CommonJS两种模块系统都有很好的支持。可以沿用以前JS的写法
我们默认一个文件就是一模块
这里着重来说一下ES6模块系统和CommonJS模块系统的区别:CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用
CommonJS模块是运行时加载,ES6模块是编译时输出接口
两者的写法也不同:12345678910111213141516171819202122//ES6导入//从module_a模块导入a和bimport {a, b} from './es6/module_a';//从module_a模块导入a,并重新起名为fimport {a as f} from './es6/module_a'//从module_a模块导入所有对象并重新起名为Allimport * as All from './es6/module_a';//从module_a模块导入Objimport Obj from './es6/module_a';//ES6导出export defalut Obj;export {a, b, c};export {d as D};//ComonJS导入let c1 = require('./node/a.ts');let c2 = require('./node/b');//CommonJS导出module.exports = a;module.exports = {};
从上边代码可以看出:
导出: ES6允许同时存在export default和export多个变量,而CommonJS只允许有一种形式的导出,其中一种会把另外一种覆盖掉。
导入: ES6可以按需导入也可以全部导入,而CommonJS只能全部导入。
ES6是未来的模块化标准,而且可以按需导入,是未来的发展方向。
- 声明文件
声明文件以.d.ts为后缀
runoob.d.ts
声明文件和模块的语法
declare module Module_Name{ }
导入声明文件语法:
///
可以看出声明文件也是模块化的一种方式,基本不使用
总结
感谢你读到了这里,如果你把这边介绍读完,基本上你就会使用TypeScript语法了。那就在开发中使用他吧。