介绍
是JS的强类型的版本,及强类型语言,Type+ES6,在编译器中去掉类型和特有的语法生成了纯JS代码
支持JS语法,在JS上添加了一些扩展,如:class/interface/module等,大大提升了代码的可读性
有静态类型检查,可以在代码开发阶段预知低级错误
ts跟js类似于 less跟css之间的关系
TypeScript在线编译器
https://www.typescriptlang.org/play/index.html
本地开发编译环境
npm i -g typescript
tsc ./ts文件名称
声明接口
// interface 声明接口
interface Person {
userName: string;
userAge: number;
}
function getAaimal(person: Person) {
return person.userName + '&&' + person.userAge;
}
let animal_01 = { userName: 'dog', userAge: 23 }
alert(getAaimal(animal_01));
声明类
class Student {
userName: string;
firstName: string;
lastName: string;
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
this.userName=this.firstName+" "+this.lastName
}
}
let stu_01 = new Student("张", "三")
alert(stu_01.userName)
类跟接口
class Student {
userName: string;
constructor(public firstName: string, public lastName: string) {
this.userName = firstName + " " + lastName;
}
}
interface Person {
firstName: string;
lastName: string;
}
function getPerson(person: Person) {
return person.firstName + " " + person.lastName;
}
let stu_01 = new Student("张", "三");
// alert(stu_01.userName)
alert(stu_01);
alert(getPerson(stu_01));
解构赋值
1,数组解构
let arr = [1, 2, 3];
let [a, b, c] = arr;
console.log(a);
console.log(b);
console.log(c);
// 上面的写法等价于:
a = arr[0];
// 利用解构赋值 交换变量
[a, b, c] = [b, c, a];
console.log(a, b, c);
// 函数参数 解构
function fun([fisrt, second]: [number, number]) {
console.log(fisrt);
console.log(second);
}
fun([1, 2]);
// 剩余参数 ...
let [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first);
console.log(rest);
// 跳过解构
let [, second, , fourth] = [1, 2, 3, 4];
console.log(second);
// 忽略其他参数
let [first1] = [1, 23, 4, 5];
console.log(first1);
2,对象解构
let obj = {
a: "abc",
b: 120,
c: "admin"
};
let a: number, b: number;
({ a, b } = {a:123,b:456})
console.log(a, b)
// 在对象中使用... 语法 创建剩余变量
let { a, ...params } = obj;
let total = params.b + params.c.length;
console.log(total); // 125
class Person {
// 属性
name: string;
age: number;
job: string;
constructor(name: string, age: number, job: string) {
this.name = name;
this.age = age;
this.job = job;
}
// 方法
sayHello() {
console.log(this.name);
}
}
// 实例化
let zs: Person = new Person("张三", 23, "软件开发");
//console.log(zs.name);
zs.sayHello();
继承1
class Animal {
Name_01: string;
move(distance: number = 0) {
//console.log(`Animal moved ${distance}m.`);
}
}
class Dog extends Animal {
bark() {
console.log("woof! woof!");
}
}
const dog = new Dog();
dog.Name_01 = "小狗";
dog.bark();
dog.move(30);
dog.bark();
// console.log(dog.Name_01);
继承2(方法重写)
class Animals {
animalName: string;
constructor(thename: string) {
this.animalName = thename;
}
move(distance: number = 0) {
console.log(`${this.animalName} moved ${distance}m.`);
}
}
class Snake extends Animals {
constructor(name: string) {
super(name);
}
move(distance = 5) {
console.log("jdjdjdjdj.....");
super.move(distance);
}
}
class Hourse extends Animals {
constructor(name: string) {
super(name);
}
move(distance = 45) {
console.log("================");
super.move(distance);
}
}
let snake = new Snake("Sammy the Python");
let tom: Animals = new Hourse("Tommy the Palomino");
snake.move();
tom.move(34);
// 注意:派生类包含了一个构造函数, 必须调用super(),
// 可以执行基类的构造函数.在构造函数里访问this的属性之前, 必须调用super()
// 上面的案例 演示了如何在子类中 重写父类的方法. Snake类和Hourse类都创建了move方法,
// 他们重写了从Animals继承来的move方法, 使得move 方法 根据不同的类而具备不同的功能.
// 注意: 即使tom被声明为Animals类型, 但是因为它的值是Hourse,调用tom.move(34)时,它会调用Hourse里重写的方法
实例对象的访问修饰符
public 开发的/公开的
成员属性和方法 默认的都有public, 可以被外部访问
class Person {
//属性
public name: string
public age:number
public constructor(name: string, age: number) {
this.name = name
this.age=age
}
//方法
public move(distance:number):void{
console.log(`${this.name} moved ${distance}m`)
}
}
let person=new Person('son',33);
//person.age;//出错 当前实例无法访问
person.move(50);
class son extends Person{
}
let Son=new son('xiao',20);
console.log(Son.name);//返回xiao
Son.age;
Son.move(30);
简便写法
class person{
constructor(public name: string, public age: number) {
this.name = name
this.age=age
}
}
private 私有的
只在类的内部访问 private修饰的成员 不能被继承 当前类的实例也不能访问
class Person {
//属性
public name:string;
private age: number;
public constructor(name: string, age: number) {
this.name = name
this.age=age
}
//方法
public move(distance:number):void{
console.log(`${this.name} moved ${distance}m`)
}
}
person=new Person('son',33);
person.move(50);
class son extends Person{}
Son=new son('xiao',20);
Son.name;
//Son.age;// 错误,无法被继承者发现
Son.move(30);
protected 受保护
可以被继承(注:只能在子类中获取父类protrcted修饰的成员属性和方法)
可以被当前类发现
class Person {
//属性
public name:string;
private age: number;
protected color:string='red';
public constructor(name: string, age: number) {
this.name = name;
this.age=age
}
//方法
public move(distance:number):void{
console.log(`${this.name} moved ${distance}m`)
console.log(this.color)
}
}
let person=new Person('son',33);
person.move(50);
class son extends Person{
public value:string=this.color
}
let Son = new son('xiao', 20,'blue');
console.log(Son.value)// 正确,被发现,返回blue
Son.name;
// Son.color;// 错误 不能在此处被发现
//Son.age;// 错误,无法被继承者发现
Son.move(30);
readonly 只读,
定值,赋值后不可进行修改,可以被继承
class Person {
//属性
public name:string;
private age: number;
protected readonly color:string='red';
public constructor(name: string, age: number) {
this.name = name;
this.age=age
}
//方法
public move(distance:number):void{
console.log(`${this.name} moved ${distance}m`);
console.log(this.color)
}
}
let person=new Person('son',33);
person.move(50);
class son extends Person{
public value:string=this.color
}
let Son = new son('xiao', 20);//,'blue');// 错误 ,color为只读,确定后不能进行修改
console.log(Son.value);// 返回red
Son.name;
// Son.color;// 错误 不能在此处被发现
//Son.age;// 错误,无法被继承者发现
Son.move(30);
私有状态下的安全继承
**属性的存(set)和取(get)**
取(get)
class person {
private name:string='张三';
private age:number=23;
private job:string='程序员';
//获取
get name1():string{
return this.name
}
//设置
set name1(newName:string){
this.name=newName
}
}
let person1=new person()
console.log(person1.name1);
存(set)
class person {
private name:string='张三';
private age:number=23;
private job:string='程序员';
//获取
get name1():string{
return this.name
}
//设置
set name1(newName:string){
this.name=newName
}
}
let person1=new person();
// console.log(person1.name1);//获取 get
person1.name1='李四';
console.log(person1.name1); //存 set
添加判断
let pwd='admin123';
class person {
private name:string='张三';
//获取
get name1():string{
return this.name
}
//设置
set name1(newName:string){
if(pwd && pwd=='admin'){
this.name=newName
}
}
}
let person1=new person();
// console.log(person1.name1);//获取 get
person1.name1='李四';
if(person1.name1){
console.log(person1.name1); //存 set
}
静态成员(static)
不需要实例化访问的成员称为静态成员即只能被当前类访问的成员
static修饰的成员属性或者方法,只能通过类名.成员名称进行访问
不能通过实例对象访问静态成员
class Math1{
static random(){
console.log('随机方法')
}
}
Math1.random(); // 可以以对象来进行调用
let math=new Math1();
// math.random();// 不可被实例化后进行调用
抽象类(abstract)
抽象类可以有普通的方法,也可以有抽象的方法,但抽象的方法不会被实现,只能在派生类中实现
抽象类,不能被实例化
abstract class person {
constructor(public name:string){
this.name=name
}
eat():void{
console.log('我可以吃')
}
abstract run():void //必须在派生类中实现,在此处不能实现该方法
}
// let person1=new person() //错误 ,抽象类不可以实例化
class son extends person{
constructor(){
super("张三")
}
move():void{
console.log(`${this.name}`)
}
run():void{// 从抽象类中继承来的方法,必须写
console.log('我可以跑')
}
}
let son1=new son();
son1.move();
son1.run();
函数
有名称的函数
function f(x:number,y:number):number {
return x+y
}
console.log(f(20,30));
匿名函数
let f1=function (x:number,y:number):number {
return x+y
};
let f2=f1(30,40);
console.log(f2);
可选参数(?:)和默认参数(在定义时给其一个默认的值)
function f3(firstName:string,lastName?:string='Bob') {
return firstName+lastName
}
// let result1=f3('Bob'); //错误,缺少一个参数
// let result2 = f3("Bob", "Adams", "Sr."); // 错误,多余一个参数
let result3 = f3("Bob", "Adams"); // 正确,参数正好
剩余参数(arguments)
会被当做个数不限的可选参数,可以一个都没有,可以有任意个,这个省略号也会在带有剩余参数的函数类型定义上使用到
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;
console.log(buildNameFun('aaaaa','dddd','ccccc'))
this和箭头函数(代码来自官网)
let deck = {
suits: ["hearts", "spades", "clubs", "diamonds"],
cards: Array(52),
// createCardPicker: function() {
// return function() {
// let pickedCard = Math.floor(Math.random() * 52);
// let pickedSuit = Math.floor(pickedCard / 13);
// return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
// //this报错 createCardPicker返回的函数里的this被设置成了window而不是deck对象。
// //只独立调用了cardPicker()
// }
// }
createCardPicker: function () {
//使用箭头函数绑定正确的this,箭头函数能保存创建时的this值,而不是调用的值
return () => {
let pickedCard = Math.floor(Math.random() * 52);
let pickedSuit = Math.floor(pickedCard / 13);
return {suit:this.suits[pickedSuit],card:pickedCard%13}
}
}
}
let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();
alert("card: " + pickedCard.card + " of " + pickedCard.suit);
重载
function fu(x:string)
function fu(x:string,y:number)
function fu(z):any {
if(typeof x=='number'){
alert(x)
}else if(typeof x=='object'){
alert(x)
}
}
fu('333'); //调用的是第一个函数
fu('222',22);//调用的是第二个函数