TypeScript学习笔记

156 阅读5分钟

Ts:以JavaScript为基础构建的语言;是一个JavaScript的超集;扩展JavaScript并添加了类型;支持在任何JavaScript平台中执行;不能被js解析器直接执行。

基本类型

image.png 类型声明

// 声明变量a,指定类型为number
let a:number;
a=10;
// 声明变量直接赋值
let b:string="wahhh"
// ts自动检测变量类型
let c=true
// 函数类型声明,参数声明
function sum(a:number,b:number):number{
    return a+b
}

// 联合类型
let a3:number | string;
a3="hellow"
a3=1
// 任意值 可以赋值给任意变量
let b3:any
a3=b3

// 未知值 不能直接赋值给其他变量
let c3:unknown
// a3=c3
// 类型断言 告诉解析器变量的实际类型
a3=c3 as string
a3=<string> c3
console.log(typeof(a3));

// 空
function fn():void{
    // alert("ddd") 
    return
}
// 永远不会有返回值
function fu2():never{
    throw new Error('报错了')
}

// object
let person:{
    name:string,
    age?:number//可选属性
}
person={
    name:"whh"
}
let per:{name:string}&{age:number}
per={
    name:"xmy",
    age:90
}
// 要求对象中需要有string类型的name属性,也可以有其他任意类型的属性
let person1:{
    name:string,
    [propName:string]:any
}
person1={
    name:"hhhh",
    a:111,
    b:true
}
// fn3为一个函数,参数和返回值限制为number
let fn3:(a:number,b:number)=>number
fn3=function(a,b){
    return a+b
}

// array
let arr1:string[]//字符串数组
arr1=["2","2"]
let arr2:Array<number>
let arr3:number[]//数字数组

// 元组tuple 固定长度的数组
let h:[string,string]
h=["e","2"]

// 枚举
enum Gender{
    Male=0,
    Female=1
}
let i :{name:string,gender:Gender}
i={
    name:"swk",
    gender:Gender.Male
}

// 类型别名
type myType=1|2|3|4|5
let k:myType
let j:myType
k=4
j=5

配置

监视当前ts文件转js文件:执行命令 tsc xxx.ts -w
监视当前目录下所有ts文件:新建tsconfig.json文件,执行命令tsc -w
tsconfig.json是ts编译器的配置文件,配置选项:

{
     // **任意目录
    // *任意文件
    // 指定文件进行编译
    "include": [
        "./test.ts","./src/**/*"
    ],
    // 排除文件编译
    "exclude": [
        "./src/test.ts"
    ],
    //编译器选项
    "compilerOptions":{
        // 指定ts被编译的js版本 默认Es3 'esnext'最新版本
        "target": "esnext",
        // 指定模块化规范
        "module": "esnext",
        // 指定项目中使用的库
        // "lib": [],
        // 指定编译后文件所在目录
        "outDir": "./dist",
        // 将代码合并为一个文件 module模块化需要是amd或者system
        // "outFile": "./dist/app.js",
        // 是否对js文件进行编译 默认false
        "allowJs": false,
        // 是否检查js代码是否符合语法规范 默认false
        "checkJs": false,
        // 是否移除注释 默认false
        "removeComments": false,
        // 不生成编译后的文件,默认false
        "noEmit": false,
        // 当有错误时不生成编译文件 默认false
        "noEmitOnError": false,

        // 语法检测
        // 所有严格检测总开关
        "strict": true,
        // 设置编译后的文件是否使用严格模式 默认false
        "alwaysStrict": false,
        // 不允许隐式any类型 默认false
        "noImplicitAny": false,
        // 不允许不明确类型的this 默认值false
        "noImplicitThis": false,
        // 严格检测空值 默认false
        "strictNullChecks": false
    }
}

面向对象

class Person{
    // 实例属性:通过对象的实例去访问
    name:string="swk";
    readonly gender:boolean=true; //无法修改
    // 类属性/静态属性:不需要创建对象就使用的属性
    static age:number=19
}
const per=new Person()
console.log(per);
console.log(per.name);
per.name="sbz"
console.log(per.name);
console.log(per.gender);

console.log(Person.age);

构造函数

class Dog{
    name:string;
    age:number
    // 对象创建时调用
    constructor(name:string,age:number){
        // this指向当前实例对象
        this.name=name
        this.age=age
        console.log("333",this);
        
    }
    // name:string;
    // age:number
    bark(){
        alert("www")
    }
}
const dog1=new Dog("小白",3)
const dog2=new Dog("小黑",4)
console.log(dog1);
console.log(dog2);

继承

class Animal{
        name:string;
        age:number
        constructor(name:string,age:number){
            this.name=name
            this.age=age
        }
        sayHellow(){
            console.log("动物在叫");
        }
    }
    // 子类继承父类所有方法和属性
    //字类可以添加父类没有的方法或方法,也可以重写父类的方法
    class Dog extends Animal{
        run(){
            console.log(`${this.name}在跑`);
        }
        sayHellow(): void {
            console.log("wwww!");
        }
    }

    class Cat extends Animal{
        sayHellow(): void {
            console.log("mmmm~");
        }
    }
    const dog1=new Dog("小白",1)
    console.log(dog1);
    dog1.sayHellow()
    dog1.run()

    const cat1=new Cat("小黄",3)
    console.log(cat1);
    cat1.sayHellow()

super

class Animal{
        name:string;
        constructor(name:string){
            this.name=name
        }
        sayHellow(){
            console.log("动物在叫");
        }
    }
    class Dog extends Animal{
        age:number;
        // 如果在子类中使用了构造函数,必须调用父类的构造函数
        constructor(name:string,age:number){
            super(name)
            this.age=age            
        }
        // super指当前类的父类
        sayHellow(): void {
            super.sayHellow()
        }
    }
    const dog=new Dog("小黄",19)
    dog.sayHellow()

抽象类

// 以abstruct开头的类是抽象类,不能用来创建对象,就是专门用来被继承的类
    abstract class Animal{
        name:string
        constructor(name:string){
            this.name=name
        }
        // 可以添加抽象方法,抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
        abstract sayHellow():void
    }
    class Dog extends Animal{
        age:number
        constructor(name:string,age:number){
            super(name)
            this.age=age
        }
        sayHellow(): void {
            console.log("wwwww");
        }
    } 
    const dog=new Dog("xioahcuang",3)
    console.log(dog.name);
    dog.sayHellow()

接口

// 描述一个对象的类型
    type myType={
        name:string,
        age:number
    }
    const obj:myType={
        name:'sss',
        age:18
    }
    //  接口用来定义一个类结构,用来定义类中包含哪些属性和方法,接口可以当成类型声明使用。可以重复声明
    interface myInterface{
        name:string,
        age:number
    }
    interface myInterface{
        gender:string
    }
    const obj1:myInterface={
        name:"ttt",
        age:18,
        gender:"man"
    }
    /*接口可以在定义类的时候去限制类的结构 
        接口中所有属性不能有实际值
        接口只定义对象的结构,不考虑实际值
        在接口中使用的方法都是抽象方法*/
    interface myInter{
        name:string,
        sayHellow():void
    }
    // 定义类时,可以使类实现一个接口
    // 实现接口就是使类满足接口的要求
    class Myclass implements myInter{
        name: string
        constructor(name:string){
            this.name=name
        }
        sayHellow(): void {
            console.log("dddd");
        }   
    }
    console.log(obj);
    console.log(obj1);
    //接口可以继承其他多个接口

属性的封装

class Person{
        // ts可以在属性前添加属性的修饰符
        /*
            public 修饰的属性可以在任意位置进行访问(修改) 默认值
            private 私有属性,只能在类内部进行访问
                    可以通过在类中添加方法修改私有属性
            protected 只能在当前类和子类中访问
        */
         name:string;
         private _age:number
        constructor(name:string,age:number){
            this.name=name
            this._age=age
        }
        get age(){
            return this._age
        }
        set age(value){
            if(value>0){
            this._age=value
            }
        }
        // setName(name:string){
        //     this.name=name
        // }
    }
    // 简易写法
    class A{
        constructor(public name:string,public age:number){
        }
        // 等价于
        // name:string;
        // age:number
        // constructor(name:string,age:number){
        //     this.name=name
        //     this.age=age
        // }
    }
    const per=new Person("swk",19)
    // per.setName("zbj")
    per.age=15//调用的是set方法
    console.log(per.age);//调用get方法
    console.log(per);

泛型

// 定义函数或是类时,遇到类型不明确就可以使用泛型
    function fn<T,K>(a:T,b:K){
        return a
    }
    console.log(fn(10,10));
    // 指定泛型
    console.log(fn<number,string>(2,"ddd"));
    
    interface Inter{
        length:string
    }
    // 泛型T必须是Inter子类
    function fn2<T extends Inter>(a:T){
        return a.length
    }

    class Myclass<T>{
        name:T
        constructor(name:T){
            this.name=name
        }
    }
    const mc=new Myclass<string>("ddd")