Typescript

107 阅读6分钟

什么是 TypeScript

TypeScript 是一种由微软开发的自由和开源的编程语言,它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。

TypeScript 扩展了 JavaScript 的语法,所以任何现有的 JavaScript 程序可以不加改变的在 TypeScript 下工作。

TypeScript基本语法

先声明后赋值:

let a:number
a=23

声明和赋值同时执行:

let a:number =134

字面量常量类似于常量:

let a:10

函数返回值类型:

function (a:number,b:number) :number{
  return a+b
}

TypeScript的数据类型分为BooleanNumberStringArrayEnumAnyVoid这七种类型。

Boolean类型
let a:boolean =false    let b:boolean = 0
Number类型
let c:number = 20.2
String类型
let d:string ="sbc"
Array类型

语法:类型[] Array<类型>

let e:sting[] =["234","xiao"]
let e:Array<string>=["234","xiao"]
Object类型

表示一个js对象,{}用来指定对象中可以包含哪些属性

let a:object
a={}
a=function(){}
​
//{}用来指定对象中可以包含哪些属性
//语法:{属性名:属性值,...}  ?表示可加可不加
let b:{name:string,age?:number}
b={name:'123',}
​
//[属性名:string]:any可以加任意类型的
let c={name:string,[x:string]:any}
b={name:'123',gender:"女",age:18}
​
设置函数结构的类型声明:

语法:(形参:类型,形参:类型...)=>返回值

let d:(a:number,b:number)=>number
d=function(n1:number,n2:number){
  return n1+n2
}
Any不确定类型

任意类型都可以,可以赋值给任何变量,

let d:any=5let d //默认就是any
let s:string
s=d
Unkown未知类型

任意类型都可以,不能直接赋值给变量

let e:unkown
//只有类型检查才可以
let s:string 
if(e === string){
 s=e
}
//类型断言也可以
s=e as string
s=<string>e 
Void类型

表示空,没有值

function a():void{
    return 
}
function a():void{
    return null/undefined
}
Never类型

永远不会返回结果

function a():never{
    throw  new Error("123")
}
Tuple类型

元组就是固定长度的数组

let d:[sting,string]
d= ['123','456']
Enum枚举类
enum Color {
 Red,
 Green
};
let c:Color =Color.Red;
//指定值:
enum Color {
    Red=1,
    Green};
let c:Color =Color.Red;
//根据值查找名称:
enum Color {
    Red=1,
    Green=2};
let c:string =Color[2];

&可以连接俩个对象

类型的别名:

type c=sting
type c = 1|2|3
let b:c
​

面向对象

在程序中所有的对象都被分成了俩个部分数据和功能,以人为例,人的姓名、性别、年龄等这些都是数据;人可以说话、走路、跑步等这些就是功能。数据在对象中被成为属性,而功能被称为方法。 eg:操作浏览器要使用window对象,操作网页要使用document对象,操作控制台要使用console对象

类(class)

差不多的意思就是分类相当于类,如动物是猫、狗的类,人是男、女的类。类中主要包括俩个部分是属性和方法。

定义类:

class 类名{
    属性名:类型;
    constructor(参数:类型){
        this.属性名=参数;
    }
    方法名(){
        ...     
    }
}

列子:

//构造函数
class Person{
    //定义实例属性这个属性是存到Person这个实例上的
    //per.name per这俩种都可以访问
    //readonly表示的是只读属性,无法修改
    readonly name:string="秃头妹";
    //在属性前使用static关键字可以定义属性(静态属性)不需要创建对象就可以用的属性
    //Person.age就可以访问(类属性)
    static readonly age:number=20;
    
    
    sayHello(){
        console.log("加油")
    }
    
    static sayHello(){
        console.log("加油")
    }
}
const per =new Person();
per.sayHello()//实例方法
Person.sayHello()//类方法
构造函数和this
//构造函数
class Dog{
    name:string
    age:number
    //constructor称为构造函数
    //构造函数会在对象创建时候调用
    constructor(name:string,age:number){
        this.name=name;
        this.age=age
    }
    
    bark(){
        console.log("汪汪")
    }
}
//new Dog()调用的时候就在调用constructor
const dog =new Dog(name:奇奇,age:3);
const dog1 =new Dog(name:怪怪,age:3);
继承
//Animal是父类,Dog和Cat是子类,都继承父类.类可以扩展,不能修改
class Animal{
    name:string
    age:number
    constructor(name:string,age:number){
        this.name=name;
        this.age=age
    }
    
    bark(){
        console.log("动物在叫")
    }
}
//子类和父类同一方法,子类会覆盖父类方法
class Dog extends Animal{   
    run(){
        console.log(`${this.name}在跑`)
    },
    bark(){
        console.log("汪汪")
    }
}
​
class Cat extends Animal{
    bark(){
        console.log("喵喵")
    }
}
​
super关键字
//匿名函数
(function(){
    class Animal{
        name:string
        constructor(name:string){
            this.name=name;
        }
    
        bark(){
            console.log("动物在叫")
        }
    }
    //没有父类哪来的子,继承了父类也就继承了父类的构造,所以也要调用
    class Dog extends Animal{
        age:number
        //如果在子类写了构造函数,子类的构造函数必须对父类的构造函数进行调用
        constructor(name:string,age:number){
            super(name)//调用父类的构造函数
            this.age=age;
        }
        bark(){
            //在类的方法中super表示当前类的父类
            super.bark()
        }
    }
    const dog =new Dog(name:奇奇;)
})()
抽象类
//以abstract开头的类是抽象类,不能用来创建对象(new Animal()),专门用来被继承的类
(function(){
    abstract class Animal{
        name:string
        constructor(name:string){
            this.name=name;
        }
        //定义一个抽象方法,没有方法体,子类必须在抽象方法中进行重写
        abstract bark():void
    }
​
    class Dog extends Animal{
        bark(){
            console.log("汪汪")
        }
    }
    const dog =new Dog(name:奇奇;)
})()
接口
(function(){
    //类型别名描述一个类型的对象,只能有一个
    type myType={
        name:string;
        age:number;
    }
    const obj:myType={
        name:'秃头',
        age:18
    }
    //接口用来定义一个类结构,包含哪些属性和方法,同时可以当成类型声明,可以有多个
    iterface myInterface{
        name:string;
        age:number
    }
    iterface myInterface{
        gender:string;
    }
    const obj:myInterface={
        name:'秃头',
        age:18
        gender:'男'
    }
    //接口可以在定义类的时候去限制类的结构,接口中所有属性都不能有实际的值。类似于抽象类,但抽象类可以接受实际的值。
    iterface myInter{
        name:string;
        sayHello():void;
    }
    //定义类时可以使类去实现一个接口,实现接口就是要求类满足接口的要求
    //一个类通过关键字implements声明自己使用一个或者多个接口
    class MyClass implements myInter{
        name:string;
        sayHello(){
            console.log('你可以!!!')
        }
    }
})()
属性的封装
(function(){
    class Person{
    //Ts可以在属性前添加属性的修饰符
    //public表示可以任意访问(修改)默认值,包括子类也可以访问
    //private表示私有属性,只能在内部类中访问,通过类中添加方法使得私有属性可以访问,但子类不可以访问
    //protected受保护的属性,只能在当前类和当前类的子类中访问
        private _name:string;
        private _age:number;
        constructor(name:string,age:number){
            this._name=name;
            this._age=age;
        }
        //查看这个可以通过per.setName('hong')
        getName(){
            return this._name
        }
        //设置
        setName(value:string){
            this._name=value;
        }
        //在Ts中设置getter方法的方式,这个获取可以per.name="ming"可以改
        get name(){
            return this._name
        }
        set name(value:string){
            this._name=value;
        }
    }
    const p=new Person(name:'xiao',age:23);
    //属性可以任意被修改导致对象中的数据变得不安全
    p.name="xiaohong"
    per.setName('hong')
    console.log(per.getName())
})()
(function(){
    class C{
        name:string;
        age:number;
         constructor(name:string,age:number){
           this.name=name
           this.age=age
         }
    }
        ||等于
    class C{
         constructor(public name:string,public age:number){
​
         }
    }
})()
泛型

在定义函数或是类时,如果遇到类型不明确就可以使用泛型。泛型就是设置一个变量,然后调用的时候指定类型。

function fn(a:any):any{
    return a
}
​
​
function fn<T>(a:T):T{
    return a
}
//可以直接调用具有泛型的函数a的类型是number
fn(a:10)//不指定泛型,TS可以自动对类型进行判断
fn<string>(a:'hello')//指定泛型//泛型可以指定多个
function fn2<T,K>(a:T,b:K):T{
    return a
}
fn2<string,number>(a:'hello',b:3)
​
//T extends Inter表示泛型T必须是Inter实现类(子类)
interface Inter{
    length:number;
}
function fn3<T extends Inter >(a:T):number{
    return a.length
}