• 【前端】TypeScript核心知识点讲解


    1.TypeScript简介及入门案例

    在这里插入图片描述

    (1)什么是TypeScript?

    TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 (ES6)标准。

    TypeScript 由微软开发的自由和开源的编程语言

    TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。

    (2)JavaScript 与 TypeScript 的区别

    TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改。

    TypeScript 通过类型注解提供编译时的静态类型检查

    TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。

    (3)TypeScript环境搭建

    • 安装node.js
    地址: https://nodejs.org/en/download/
    
    • 1
    • 检查安装情况
    node -v
    
    • 1
    • npm配置国内镜像源
    npm config set registry https://registry.npm.taobao.org
    
    配置之后可以验证是否成功:
    npm config get registry
    
    • 1
    • 2
    • 3
    • 4
    • 使⽤npm全局安装typescript
    npm i -g typescript
    
    • 1
    • 验证
    tsc -v
    
    • 1
    Version 5.2.2
    
    • 1

    (4)编写第一个TS程序

    • 创建demo.ts
    console.log('李祥');
    
    • 1
    • 编译成js文件
    tsc demo.ts
    
    • 1
    • html引入js文件

    在这里插入图片描述

    2.TypeScript基础数据类型

    (1)TS中的类型声明

    类型声明是TS中⾮常重要的特点。

    通过类型声明可以指定TS中变量(形参)的类型。

    指定类型后,当变量赋值时,TS编译器就会⾃动检查值是否符合声明类型,如果符合就赋值,不符合就报错。

    简单的说,类型声明就是给变量设置了类型。使得变量只能存储某种类型的值。

    • 语法:
    let 变量名:类型;//只声明,未赋值
    let 变量名:类型=;//声明并赋值 
    function fun(参数:类型,参数:类型):类型{}
    
    • 1
    • 2
    • 3
    • TS的基础数据类型

      • number类型:双精度64位浮点值。它可以用来表示整数和分数。

      • boolean类型:表示逻辑值:true和false

      • string类型:一个字符系列,使用单引号(')或双引号(")来表示字符串类型。反引号(`)来定义多行文本和内嵌表达式

    (2)TS自动类型判断

    • 什么是⾃动类型判断
    TS拥有⾃动类型判断机制。
    当对变量的声明和赋值同时进⾏时,TS编译器会⾃动判断变量类型。
    所以如果你的变量的声明和赋值是同时进⾏的,可以省略掉类型声明。
    
    • 1
    • 2
    • 3
    • 案例
    //声明一个变量未赋值
    let num:number;
    
    num = 7;
    
    //声明一个变量进行赋值
    let sum = 9;
    
    console.log(typeof num);
    console.log(typeof sum);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 控制台打印:
    number
    number
    
    • 1
    • 2
    • 如果强行将sum赋值string类型 会编译报错

    在这里插入图片描述

    (3)TS字面量声明

    • 什么是字面量
    客观存在⽆法改变的值。
    
    • 1
    • 字面量声明
    //使⽤字⾯量声明后a的值,永远是23 相当于常量不能修改
    let a:23;
    //如果修改ts就会提醒
    const a=23;
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    (4)TS中的any类型

    any表示任意数据类型,⼀个变量设置类型为any后相当于对该变量关闭了TS的类型检测。

    //显式的any类型声明
    let a:any;
    a=12;
    a=true;
    a="lixiang";
    
    //隐私的any类型声明,声明如果不指定类型,则TS解析器会⾃动判断变量的类型为any
    let b;
    b=23;
    b=false;
    b="lixiang";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    使用any类型的变量可以被赋值为任何类型的值,而不会导致编译器报错或警告。使用any类型时需要注意,因为它是一个非常灵活的类型,可能会导致类型不一致或意外的行为。

    (5)TS中unknown类型

    unknown是TypeScript中比较特殊的一种类型,它用于描述类型不确定的变量。这与any类型相似,但更安全,因为对未知值做任何事情都是不合法的。

    unknown:表示未知类型的值;
    let b:unknown;
    b=123;
    b=true;
    b='lixiang';
    
    let c:unknown;
    c='123';
    let d:string;
    
    d=c;
    //此时TS解析器提示是报错的
    //虽然 变量中的字⾯量都是string,但是 d是string类型c是unknown所以不能赋值
    //假如我就想让c的值赋值给d,应该这样操作
    if(typeof c ==='string'){
     d=c;//这样就可以完成赋值了
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    (6)TS中的类型断⾔

    类型断⾔:可以⽤来告诉TS解析器变量的实际类型

    语法:

    • 变量 as 类型;
    • 变量;
    利⽤类型断⾔来处理上⼀节的unknown赋值的⼩问题
    let c:string;
    let d:unknown;
    d="lixiang";
    c=d as 'string';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    console.log(typeof c);
    
    • 1
    输出结果:string
    
    • 1

    3.TypeScript的函数声明

    (1)对函数中形参进⾏类型声明

    与JavaScript不同的是TypeScript函数声明中增加了对形参类型的声明

    function fun(num1:number,num2:number):number{
     	 return num1+num2;
    }
    
    • 1
    • 2
    • 3

    这样声明的函数,参数只能传递两个数值类型的值,返回也是一个数值类型的值。

    所以传入一个参数,或者传入的参数不是数字的编译器都会报错。

    //传递不是number的实参
    fun('li','xiang');
    
    //多参数
    fun(123,4556,55,56);
    
    //少参数
    fun(11);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (2)函数中返回值类型的声明

    • 不设置返回值类型,但是有返回值
    function fun(){
     	return true;
    }
    
    //这个时候TS解析器会根据返回值的类型进⾏判断,返回值类型是什么函数返回值类型就是什么
    let result=fun();
    console.log(typeof result);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    打印结果:boolean
    
    • 1
    • 设置返回值类型为void
    //void:⽤来表示空,以函数为例,就表示没有返回值的函数
    function fun():void{
     	return;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 设置返回值类型为 never
    //never:永远不会返回结果
    function fun():never{
     	throw new Error("异常");
    }
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4.TypeScript复杂数据类型

    (1)对象类型声明

    let a:object; //声明一个object对象类型的数据
    let b:{name:string};//声明一个对象b,里面有个string类型的name属性
    //给b变量赋值
    b={name:'lixiang'}
    
    • 1
    • 2
    • 3
    • 4
    • 语法:
    {属性名1:属性值1,属性名2:属性值2}
    当我们采用这种方式指定对象的时候,必须要求格式一摸一样。
    
    • 1
    • 2
    • 指定的对象它必须包含⼀个name,但是还有age和sex这个俩个变量是可能有可能有没有的,这种情况我们该怎样做?
    let b:{name:string,age?:number,sex?:string}; // 在属性后面加个?表示这个属性非必需
    
    • 1
    b={name:'lixiang'};
    b={name:'zhangsan',age:18};
    
    • 1
    • 2
    • 当我们只知道我们必须有的属性,⽽其他的不必须我们不知道,该怎么处理?
    let b:{name:string,[propName:string]:unknown};
    //这就表示我们指定b中存储的类型是对象,并且这个对象必须含有⼀个name的属性,类型为string,这个对象还可以有其他可选属性,只要属性名满⾜是字符串,属性值是unknown即可
    
    • 1
    • 2
    [propName:string]:这个任意命名,就表示属性的名字,这个属性名字的类型是string。js中属性名⼀般都是⽤string定义。
    [propName:string]:unknown;合起来就代表属性名为string类型,为可选的并且这个属性的值为unknown类型。
    
    • 1
    • 2

    (2)数组类型声明

    第一种:let 变量名:类型名[];
    第二种:let 变量名:Array<类型名>;
    
    • 1
    • 2
    let e:string[]; //声明一个字符串类型的数组,表示e中只能存储字符串
    let d:number[]; //声明一个数字类型的数组
    let f:boolean[]//声明一个boolean类型的数组
    let e:Array<number>; //另一种方式声明数值类型的数组
    let e:Array<any>; //声明一个存储任意类型的数组
    let e:any[]; //声明一个存储人意类型的数组
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (3)元组类型声明

    元组(tuple)就是定⻓的数组。且类型自定义,类型相互对应。

    let h:[string,string];//定义元组存储两个值,第⼀个值是string类型。第⼆个值也是string
    //定义的时候多⼀个少⼀个也不⾏,必须按照声明的结构定义数组,不然TS解析器就会提示报错
    h=['li','xiang'];
    
    let s:[string,number]//定义元组存储两个值,第⼀个值是string类型。第⼆个值是number
    s=['s',1];
    元组书写语法:[类型,类型,类型];
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (4)枚举类型声明

    枚举(Enum),可以定义⼀些带名字的常量。⽤于清晰地表达意图或创建⼀组有区别的⽤例。

    • 语法:
    enum 枚举名称{成员1,成员2....};
    
    • 1
    • 数字枚举:
    // 默认情况下,第⼀个枚举值是0,后续⾄依次增1
    enum Color
    {
     red,
     blue,
     yellow
    }
    alert(Color.blue);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 字符串枚举
    enum Gender {
     male = '1',
     female = '0',
    }
    alert(Gender.male);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (5)联合类型声明

    在ts中我们可以使⽤ "|" 进⾏联合类型声明
    语法:let 变量名:声明类型1|声明类型2.....;
    //就表示声明⼀个变量名,它可以是类型1还可以是类型2或者更多
    
    let sex = string:number;
    sex = 1;
    sex='1'
    //这两种赋值方式都可以
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (6)类型别名

    • 声明一个类型别名:type t = ‘’;

    • 声明一个a的类型变量:type a = 1|2|3|4|5|;

    • 这时我们声明一个b变量:let b = a; b就等价于let b = 1|2|3|4|5|;

    5.TypeScript中的配置

    (1)⾃动编译⽂件

    • ⾃动编译单个⽂件
    编译⽂件时,使⽤-w指令后,TS编译器会⾃动监视⽂件的变化,并在⽂件发⽣改变时对⽂件进⾏重新编译。
    tsc ⽂件名.ts -w
    
    • 1
    • 2
    • ⾃动编译当前项⽬下的所有的ts⽂件
    如果直接使⽤tsc指令,则可以⾃动将当前项⽬下的所有的ts⽂件编译成js⽂件。
    要在项⽬的根⽬录下创建⼀个ts的配置⽂件 tsconfig.json。tsconfig.json是⼀个json⽂件,添加配置后,只需要tsc命令即可完成对整个项⽬的编译。
    
    • 1
    • 2

    (2)tsconfig.json中的配置项讲解

    • include:定义希望被编译⽂件所有的⽬录
    默认值:[**/**]
    案例:"include":["dev/**/*","prop/**/*"] 
    **:表示任意⽬录
    *:表示任意⽂件
    就代表所有的dev⽬录和prop⽬录下的⽂件都会被编译
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • exclude:定义不需要编译的⽬录
    默认值:["node_modules","bower_components","jspm_packages"]
    案例:"exclude":["./prop/**/*"]
    代表不编译prop⽬录下的所有⽂件
    
    • 1
    • 2
    • 3
    • extends:定义被继承的配置⽂件
    案例:"extends":"./config/base"
    表示当前配置⽂件会⾃动包含config⽬录下base.json中的所有配置信息
    
    • 1
    • 2
    • files:指定需要编译⽂件的列表
    案例:
     "files":
     [
     "one.ts",
     "two.ts",
     "three.ts",
     "four.ts"
     ]
    表示列表中⽂件都会被TS编译器编译
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • complierOptions:ts编译时的配置
    target:指定ts编译的js⽬标版本
    可选值:"ES3"(默认), "ES5""ES6"/ "ES2015""ES2016""ES2017""ESNext"。
    案例:"compilerOptions":{"target":"ES6"}
    表示我们所编写的ts代码将会被编译ES6版本的js代码
    
    • 1
    • 2
    • 3
    • 4
    module:指定使⽤的模块化规范
    可选值:"None""CommonJS""AMD""System""UMD""ES6""ES2015"。
    只有 "AMD""System"能和 --outFile⼀起使⽤。
    "ES6""ES2015"可使⽤在⽬标输出为 "ES5"或更低的情况下。
    
    • 1
    • 2
    • 3
    • 4
    lib:指定编译过程中需要引⼊的库⽂件的列表
    可选值:"ES5""ES6""ES2015""ES7""ES2016""ES2017""ES2018""ESNext""DOM""DOM.Iterable""WebWorker""ScriptHost""ES2015.Core""ES2015.Collection""ES2015.Generator""ES2015.Iterable""ES2015.Promise""ES2015.Proxy""ES2015.Reflect""ES2015.Symbol""ES2015.Symbol.WellKnown""ES2016.Array.Include""ES2017.object""ES2017.Intl""ES2017.SharedMemory""ES2017.String""ES2017.TypedArrays""ES2018.Intl""ES2018.Promise""ES2018.RegExp""ESNext.AsyncIterable""ESNext.Array""ESNext.Intl""ESNext.Symbol"
    案例:
     "compilerOptions":{
     "target":"ES6",
     "lib":["ES6","DOM"]
     }
    注意:如果--lib没有指定默认注⼊的库的列表。默认注⼊的库为:
    针对于--target ES5:DOM,ES5,ScriptHost
    针对于--target ES6:DOM,ES6,DOM.Iterable,ScriptHost
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    outDir:⽤来指定编译后⽂件所在的⽬录
    案例:
     "compilerOptions":{
     "target":"ES6",
     "lib":["ES6","DOM"],
     "outDir":'./dist'
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    outFile:将编译的代码合并成⼀个⽂件
    案例:
     "compilerOptions":{
     "target":"ES6",
     "lib":["ES6","DOM"],
     "outDir":'./dist',
     "outFile":'./dist/main.js'
     }
    "outFile":'./dist/main.js'
    就表示把编译后的⽂件合并的main.js这⽂件中,最后只会输出⼀个js⽂件
    mudule只能使⽤ amd或者是system
    其实outFile这个功能我们在⼯作中也很少使⽤,因为我们打包的时候都是通过打包⼯具进⾏使⽤的。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    allowJs:是否对js⽂件进⾏编译
    默认值:false
    案例:"allowJs":true
    
    • 1
    • 2
    • 3
    checkJs:是否检查js代码符合语法规范
    默认值:false
    案例:"checkJs":true
    
    • 1
    • 2
    • 3
    removeComments:在编译的时候是否移除注释
    默认值:false
    
    • 1
    • 2
    noEmit:不⽣成编译后的⽂件
    默认值为:false
    案例:"noEmit":true
    
    • 1
    • 2
    • 3
    noEmitOnError:当存在语法错误的时不⽣成编译后的⽂件
    默认值:false
    案例:"noEmitOnError":true
    
    • 1
    • 2
    • 3
    alwaysStrict:js中有⼀种模式叫做严格默认,它语法更严格,在浏览器执⾏的性能更⾼,开发时候我们都会让我们的代码在严格模式下执⾏。
    如果是在js⽂件的话 只需要在js⽂件的开头加⼊⼀个字符串。
    "use strict";
    设置编译后的⽂件是否使⽤严格模式
    默认值:false
    案例:"alwaysStrict":true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    noImplicitAny:不允许隐式的any类型
    默认值为:false
    案例:"noImplicitAny":true
    
    • 1
    • 2
    • 3
    strictNullChecks:严格的检查空值
    默认值为:false
    案例:"strictNullChecks":false
    
    • 1
    • 2
    • 3
    strict:所有严格检查的总开关
    默认值为:false
    案例:"strict":false
    
    • 1
    • 2
    • 3

    6.TypeScript语法进阶

    (1)直接运⾏ts⽂件

    • ⾸先全局安装ts-node
    npm install -g ts-node
    
    • 1
    • 执⾏ts-node命令即可
    ts-node hello.ts
    
    • 1
    运行结果:hello lixiang
    
    • 1

    (2)TypeScript中的类

    • 如何定义类
    //通过class这个关键字来定义⼀个类
    class Person{
     name:string;
     age:number;
    }
    //通过这个类实例化⼀个对象
    let person=new Person;
    如果不传递参数的话()可以省略
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 静态修饰符(static)
    static修饰的属性或者是⽅法,属于类的。可以通过类名调⽤,不属于实例的,实例没办使⽤
    class Person {
      static name: string = "lixiang";
      static sayHello() {
        console.log("你好!");
      }
    }
    Person.sayHello();
    使⽤⽅法:放在属性名或者⽅法名前⾯
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • readonly只读
    被readonly修饰的属性,只能读取不能修改
    案例:Person.full_name='lixiang'
    • 1
    • 2

    在这里插入图片描述

    (3)类中的构造⽅法

    • 如何在类中定义⼀个构造⽅法
    class Dog{
     constructor(){
     		console.log("我创建⼀个Dog");
     }
    }
    const dog=new Dog();
    //当我们调 new Dog();的时候我们就等于调⽤Dog中的构造⽅法
    //在实例犯法中,this就表示当前的实例
    //在构造⽅法中当前对象及时当前新建的那个对象
    //可以通过this向新建的对象中添加属性
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 定义⼀个有参构造⽅法
    class Dog {
      constructor(name: string) {
        console.log(name);
      }
    }
    const dog = new Dog("黑妞");
    //创建的时候必须传递⼀个string类型的参数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • this改造构造⽅法
    class Dog {
      name: string;
      constructor(name: string) {
        this.name = name;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (4)TS中的继承

    class Animal {
      name: string;
      constructor(name: string) {
        this.name = name;
      }
      eat() {
        console.log(this.name + "吃东西");
      }
    }
    class Dog extends Animal {
      constructor(name: string) {
        super(name);
      }
    }
    此时,Animal被称为⽗类,Dog被称为⼦类,使⽤继承后,⼦类将会拥有⽗类所有的⽅法和属性。
    通过继承可以将多个类中共有的代码写在⼀个⽗类中。
    这样只需要写⼀次即可让所有⼦类都同时拥有⽗类中的属性和⽅法。
    如果希望在⼦类中添加⼀些⽗类中没⼜的属性或⽅法直接加就⾏。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    (5)TS中的重写

    重写父类的方法,子类中会覆盖掉父类的方法

    
    class Animal{
        name:string="动物";
        sleep(){
            console.log("动物在睡觉");
        }
    }
    
    class Dog extends Animal{
        name:string="狗";
        sleep(){
            console.log("狗在睡觉");
        }
    }
    
    let jm=new Dog();
    console.log(jm.name);
    jm.sleep();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    运行结果:
    狗在睡觉
    狗
    
    • 1
    • 2
    • 3

    (6)super关键字

    1:在当前类中 super就表示当前类的父类
    
    2:如果在子类中写了构造方法,在子类构造方法中必须对父类的构造方法进行调用
    
    子类不写构造方法,父类将自动调用,如果子类写构造方法,则会把父类构造方法覆盖调用,所有必须调用父类的构造方法
    
    super();//有参数也需要传递对应的参数,不然会TS解析器会提示报错
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    class Animal{
        name:string;
        sleep(){
            console.log(this.name+"在睡觉");
        }
        constructor(name:string){
            this.name=name;
        }
    }
    
    class Dog extends Animal{
        age:number;
        sleep(){
            //super   代表父类   父类 -》超类
            super.sleep();
        }
        constructor(name:string,age:number){
            super(name);
            this.age=age;
        }
    }
    
    let jm=new Dog("金毛",12);
    jm.sleep();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    运行结果:
    金毛在睡觉
    
    • 1
    • 2

    (7)TS中的抽象类

    • 抽象类
    以abstract开头的类被称为抽象类,抽象类和其他类区别不大,只是不能用来创建对象。抽象类就是专门用来被继承的类。
    
    • 1
    • 抽象方法
    抽象类中可以添加抽象方法
    抽象方法使用abstract开头,没有方法体
    抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
    abstract syaHello():void;
    
    • 1
    • 2
    • 3
    • 4
    abstract class Animal{
        name:string="抽象类";
        abstract sleep():void;
    }
    
    class JM extends Dog{
        sleep(){
           console.log("狗在睡觉");
        }
    }
    let jm = new JM();
    jm.sleep();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    运行结果:
    狗在睡觉
    
    • 1
    • 2

    (8)TS中的接口

    • 接口
    接口用来定义一个类结构,用来定义一个类中应该包含哪些属性和方法。同时接口也可以当成类型声明去使用。接口可以重复声明,取所有相同接口名的并集
    
    • 1
    • 语法
    通过 interface 关键字来定义
    
    • 1
    //interface
    interface myInterface{
        name:string;
        sleep():void;
    }
    interface myInterface{
        age:number;
    }
    class Person implements myInterface{
        name:string;
        age:number;
        gender:string;
        sleep(){
            console.log(this.name+"睡觉");
        }
        constructor(name:string,age:number,gender){
            this.name=name;
            this.age=age;
            this.gender=gender;
        }
    }
    
    let c=new Person('lixiang',19,'男');
    c.sleep();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    运行结果:
    lixiang睡觉
    
    • 1
    • 2

    (9)TS中属性的封装

    • 属性修饰符
    public:修饰的属性可以在任意位置访问,是默认值
    private: 私有属性,私有属性只能在类内部进行访问,通过在类中添加方法使得私有属性可以被外部访问
    protected: 受保护的属性,只能在当前类何当前类的之类中访问
    
    • 1
    • 2
    • 3
    • 属性封装
    class Person {
        private name:string;
        private age:number;
        constructor(name:string,age:number){
            this.name=name;
            this.age=age;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 属性存取器
    getter 方法用来读取属性
    setter 方法用来设置属性
    
    class Person {
        private name:string;
        private age:number;
        constructor(name:string,age:number){
            this.name=name;
            this.age=age;
        }
        get name():string{
            return this.name;
        }
        set name(name:string):void{
            this.name=name;
        }
    }
    let obj =new Person("lixiang",18);
    obj.setAge=12;
    console.log(obj.getAge);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    运行结果:
    12
    
    • 1
    • 2

    (10)TS中的泛型

    • 泛型的使用场景
    在定义函数或类时,如果遇到类型不明确就可以使用泛型
    泛型就是一个不确定的类型
    
    • 1
    • 2
    • 使用简单的泛型
    function cache<泛型名>(value:泛型名):泛型名{
        return 泛型名;
    }
    
    • 1
    • 2
    • 3
    • 泛型的约束
    我们可以指定泛型的类型,如果我们不指定TS解析器会根据我们传递的参数进行类型推测(建议我们在使用泛型的时候指定泛型的类型)
    使用方法:
    cache<指定泛型类型>('lixiang');
    
    • 1
    • 2
    • 3
    • 创建多个泛型
    function cache<泛型名1,泛型名2>(value1:泛型名1,value2:泛型名2):T{
        return T;
    }
    
    cache<泛型类型1,泛型类型2>(实参1,实参2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 泛型在接口中的使用
    interface Animal<T>{
        name:T;
    }
    
    class Dog<T,F>  implements Animal<T>{
        name:T;
        age:F;
        constructor(name:T,age:F){
            this.name=name;
            this.age=age;
        }
    }
    let jm=new Dog<string,number>("黑妞",12);
    console.log(jm.name);
    console.log(jm.age);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    运行结果:
    黑妞
    12
    
    • 1
    • 2
    • 3

    记得给博主三连哦!!!
    在这里插入图片描述

  • 相关阅读:
    如何使用Blender制作360度全景图和全景视频?
    XML对代码中的空白处理
    基于springboot+vue的在线音乐播放点播分享平台 elementui
    Spring Security 在登录时如何添加图形验证码
    Pytest自动化测试框架:mark用法---测试用例分组执行
    MySQL读写分离之一主一从
    【Linux-Linux发展史和环境安装】开源的力量!
    Mybatis-Plus的介绍和使用
    归并排序算法
    【Python数据科学快速入门系列 | 07】Matplotlib数据可视化基础入门(二)
  • 原文地址:https://blog.csdn.net/weixin_47533244/article/details/134342052