什么是ts(TypeScript)
TypeScript是微软开发的一个开源的编程语言,通过在JavaScript的基础上添加静态类型定义构建而成。TypeScript通过TypeScript编译器或Babel转译为JavaScript代码,可运行在任何浏览器,任何操作系统。
TypeScript添加了很多尚未正式发布的ECMAScript新特性(如装饰器 )。2012年10月,微软发布了首个公开版本的TypeScript,2013年6月19日,在经历了一个预览版之后微软正式发布了正式版TypeScript。
ts配置
先到官网下载NodeJS,安装好NodeJS后,以管理员身份运行终端,使用npm -g install ts-node typescript命令进行全局安装。
let 与 const
声明变量的时候,我们推荐是用let和const,而不推荐使用var,并加上类型说明,且作用域为块级即以{}为界。
let lang: string = 'hello world';//如果省略类型说明,TS也可进行自动推断
lang =2022 ;//赋值错误! 如果需要可以使用联合类型:let lang: number | string = 'TS';
let age: number = 20;
let age = 35;//这个也是错误的,原因是和上面一样的!
const num: number = 6.66666;//num以后不可改变,只可以读取,类似常量
num = 3.14;//错误
解构
将对象、数组中的元素拆分到指定变量中,以方便使用。
//解构数组
let array = [1, 2, 3, 4];
let [one, two] = array;//注意使用[]
console.log(one); // 1
console.log(two); // 2
let [first, ...others] = array; //剩余变量。...others是一个可变长度的数组
console.log(...others);
//展开
let newArr = [0, ...others, 5];
console.log(newArr);
//解构对象
let People = {
name: "xiaoyi",
age: 20,
sex: "male"
};
let {name, age} = People;//注意使用{},且变量名需与对象中道属性名一致
console.log(name, age);
函数
需要使用完整函数类型定义。
//命名函数,有完整的参数和返回类型。可以不用,TS将自动进行类型推断但推荐使用!
function sum(x: number, y: number): number {
return x + y;
}
//匿名函数
let res_sum = function(x: number, y: number): number { return x + y; };
console.log(sum(1, '2'));//参数类型必须和形参的类型一致
console.log(sum(1));//参数个数必须和函数的形参个数一致
console.log(typeof sum(1, 2));//打印出函数的返回值类型
可选参数
//可选参数,必须放在必要参数后
function greeting(firstName: string, lastName?: string) {
if(lastName) {//判断lastname是否有值传进来
return `Hello ${firstName} ${lastName}!`;//使用模板字符串进行拼接
}
return `Hello ${firstName}!`;
}
console.log(greeting('周'));
console.log(greeting('周', '晓忆'));
console.log(greeting('周', '晓忆', '你好'));//参数个数和函数的新参个数不一致,产生错误。
默认参数【有缺省值】
//默认参数,不必在必要参数后
function greeting(firstName: string, lastName = 'yinjie') {
return `Hello ${firstName} ${lastName}!`;
}
console.log(greeting('zhou'));
console.log(greeting('zhou', 'xiaoyi'));
console.log(greeting('zhou', 'xiaoyi', 'Yong'));//参数个数与函数的形参个数不一样发生错误!
剩余参数
必要参数,默认参数和可选参数有个共同点:它们表示某一个参数。 有时,你想同时操作多个参数,或者你并不知道会有多少参数传递进来, 在TypeScript里,你可以把所有参数收集到一个变量里
//剩余参数,会被当做个数不限的可选参数。可以一个都没有,也可以有任意个
function greeting(firstName: string, ...restName: string[]) {//...代表的是一个可变长度的数组
return `Hello ${firstName} ${restName.join(' ')}!`;
}
console.log(greeting('zhou', 'wang', 'li', 'liu', 'guan', 'zhang', 'qin'));
console.log(greeting('zhou'));
箭头函数
特点:简化函数定义、解决this问题。但是可读性比较差。
//无参数,函数体代码只有一行,则该行结果即为函数返回值
let greeting1 = () => `Hello TS!`;
console.log(greeting1());
//一个参数,函数体代码只有一行,则该行结果即为函数返回值
let greeting2 = (name: string) => `Hello ${name}`;
console.log(greeting2('QiGe'));
//两个及以上的参数,函数体代码只有一行,则该行结果即为函数返回值
let add1 = (n1: number, n2: number) => n1 + n2;
console.log(add1(1, 2));
//两个及以上的参数,函数体代码多于一行,则必须用{}包裹,且显式给出return
let add2 = (n1: number, n2: number) => {
let sum = n1 + n2;
return sum;//改为sum++结果如何?
}
console.log(add2(1, 2));
类class
类是属性和函数的集合,是生成对象(Object)或类实例的模板。
类的定义和使用
//getter和setter
class People { //class是关键字,类名默认全部大写首字母
private readonly _name: string; //私有属性,外部不可访问。readonly使其只能在初始化时赋值,以后不可更改。
private _sex: string; //私有属性,习惯以_开头进行命名
constructor(name: string, sex: string){ //构造函数,一般用于初始化
this._name = name;
this._sex = sex;
}
get name(): string {
return this._name;
}
set name(value: string) { //错误! _name有readonly属性,不可以被修改
this._name = value;
}
get sex(): string {
return this._sex;
}
set weather(sex: string) {
this._sex = sex;
}
}
let people = new People('zhouxiaoyi', 'male'); //使用new关键字生成对象
console.log(people.name, people.weather);
people.weather = 'sunny'; //OK
people.name = 'Wang'; //只读属性,不可以被修改
console.log(people);
静态属性
类中的属性或函数有static修饰,则可直接使用而不需要实例化
//静态属性,内建或自定义,无需new即可使用,可以直接通过类名进行访问
//Math是一个包装类,自带的,里面的所有方法都是静态的。
console.log(Math.round(89.64)); //90
console.log(Math.pow(2, 8)); //256
class Tool {
static title = 'box';
static printInfo() {
console.log('The box can contain pens!');
}
}
//静态方法与静态函数可以直接通过类名直接访问。
console.log(Tool.title);
Tool.printInfo();
继承
面向对象有三大特性:封装、继承、多态。
可以通过extends关键字继承其它类,从而成为其子类。
class Animal {
// 当构造函数传入的参数加上了“访问权限控制符”,则同时会声明同名类属性,并赋值
constructor(public name: string) { }
protected log(message: string) {
console.log(message);
}
move(distanceInMeters: number = 0) {
this.log(`${this.name} moved ${distanceInMeters}m.`);//请注意name来自何处
this.log('==============');
}
}
class Horse extends Animal {
constructor(name: string) {
super(name); // 通过super调用父类构造器
}
run(distanceInMeters = 50) { //自己独有的函数
this.log("Clop, clop...");
super.move(distanceInMeters); // 通过super调用父类方法
}
}
class Eagle extends Animal {
constructor(name: string) { super(name); }
reborn() { //自己独有的函数
console.log('Reborn? It is a joke, hahaha!');
}
}
let tom: Horse = new Horse("Tommy the Palomino");
tom.run(8964);
let sam: Eagle = new Eagle("Sammy the Hawk");
sam.move(1024);//sam的move函数来自何处?
sam.reborn();
模块Module
对于大型的项目,我们需要使用模块进行管理。每个 .ts 文件就是一个模块,通过 export 来对外部模块暴露元素,通过 import 来引入模块。这个就和很多语言中的import的方法大同小异了。
文章参考网址:qige.io
如果想进一步学习TS,那么就进入官网:https://www.tslang.cn/