TS学习与实践

文章目录

  • 学习资料
  • TypeScript 介绍
    • TypeScript 是什么?
    • TypeScript 增加了什么?
    • TypeScript 开发环境搭建
  • 基本类型
  • 编译选项
    • 声明
    • 属性
    • 属性修饰符
    • getter 与 setter
    • 方法
      • static 静态方法
      • 实例方法
    • 构造函数
    • 继承 与 super
    • 抽象类
    • 接口
      • interface 定义接口
      • implements 使用接口
      • 多重继承
    • 泛型


学习资料

【尚硅谷TypeScript教程(李立超老师TS新课)】

TypeScript演练场

TypeScript 介绍

TypeScript 是什么?

在这里插入图片描述

TypeScript 增加了什么?

在这里插入图片描述

TypeScript 开发环境搭建

  1. 下载Node.js https://nodejs.com.cn/
  2. 安装Node.js
  3. 使用npm全局安装typescript
    • 进入命令行
    • 输入:npm i -g typescript
  4. 创建一个ts文件
  5. 使用tscts文件进行编译
    • 进入命令行
    • 进入ts文件所在目录
    • 执行命令:tsc 文件名.ts

基本类型

  • 类型声明

    • 类型的声明是TS非常重要的一个特点
    • 通过类型声明可以指定TS中的变量(参数、形参)的类型
    • 指定类型后,当为变量赋值时,TS编译器会自动检查是否符合类型声明,符合则赋值,否则报错
    • 简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值
    • 语法:
      let 变量: 类型;let 变量: 类型 =;function fn(参数:类型, 参数:类型): 类型{...
      }
      
  • 自定类型判断

    • TS拥有自动的类型判断机制
    • 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
    • 所以如果你的变量的声明和赋值是同时进行的,可以省略掉类型声明
  • 类型

    类型例子描述
    number1, -33, 2.5任意数字
    string‘hi’, “hi”任意字符串
    booleantrue、false布尔值true 或 false
    字面量其本身限制变量的值就是该字面量的值
    any*任意类型
    unknown*类型安全的any
    void空(undefined)没有值(或 undefined)
    never没有值不能是任何值
    object{name:‘孙悟空’}任意的JS对象
    array[1,2,3]任意JS数组
    tuple[4,5]元素,TS新增类型,固定长度数组
    enumenum{A,B}枚举,TS中新增类型
  • number

    let decimal: number = 6;
    let hex: number = 0xf00d;
    let binary: number = 0b1010;
    let octal: number = 0o744;
    let big: bigint = 100n;
    
  • boolean

    let isDone: boolean = false;
    
  • string

    let color: string = "blue";
    color = 'red';let fullName: string = `Bob Bobington`;
    let age: number = 37;
    let sentence: string = `Hello, my name is ${fullName}.I ll be ${age +1} years old next month.`
  • 字面量
    也可以使用字面量去指定变量的类型,通过字面量可以确定变量的取值范围

    let color: 'red' | 'blue' | 'black';
    let num: 1 | 2 | 3 | 4 | 5;
    
  • any

    let d: any = 4;
    d = 'hello';
    d == true;
    
  • unknown

    let notSure: unknown = 4;
    notSure = 'hello';
    
  • void

    let unsable: void = undefined;
    
  • never

    function error(message: string): never {throw new Error(message);
    }
    
  • object(没啥用)

    let obj: object = {};
    
  • array

    let list: number[] = [1,2,3];
    let list: Array<number> = [1,2,3];
    
  • tuple

    let x: [string, number];
    x = ["hello",10];
    
  • enum

    enum Color {Red,Green,Blue
    }
    let c: Color = Color.Green;enum Color {Red = 1,Green = 2,Blue = 4
    }
    let c: Color = Color.Green;
    
  • 类型断言

    • 有些情况下,变量的类型对于我们来说是很明确,但是TS编译器却不清楚,此时,可以通过类型断言来告诉编译器变量的类型,断言有两种形式:
      • 第一种
        let someValue: unknown = "this is a string";
        let strLength: number = (someValue as string).length;
        
      • 第二种
        let someValue: unknown = "this is a string";
        let strLength: number = (<string>someValue).length;
        

编译选项

  • 自动编译文件
    • 编译文件时,使用-w指令后,TS编译器会自动监视文件的变化,并在文件发生变化时对文件进行重新编译。
    • 示例:
      • tsc xxx.ts -w
  • 自动编译整个项目
    • 如果直接使用tsc指令,则可以自动将当前项目下的所有ts文件编译为js文件。
    • 但是能直接使用tsc指令的前提是,要先在项目目录下创建一个ts的配置文件tsconfig.json
    • tsconfig.json是一个JSON文件,添加配置文件后(添加配置文件命令,在VSCode终端中输入tsc -init),只需要tsc指令即可完成对整个项目的编译。
    • 配置选项:
      • include
        • 定义希望被编译文件所在的目录
        • 默认值:[**/*]
        • 示例:
          "include":["src/**/*","tests/**/*"]
          
          上述例子中,所有src目录和tests目录下的文件都会被编译
      • exclude
        • 定义需要排除在外的目录
        • 默认值:["node_modules","bower_components","jspm_packages"]
        • 示例:
          "exclude": ["./src/hello/**/*"]
          
          上述示例中,src和hello目录下的文件都不会被编译
      • extends【了解即可】
        • 定义被继承的配置文件
        • 示例:
          • "extends": "./configs/base"
            上述示例中,当前配置文件会自动包含config目录下base.json中所有配置信息
      • files【了解即可】
        • 指定被编译文件的列表,只需要编译的文件少时才会用到
        • 示例:
          "files": ["core.ts","sys.ts","types.ts"
          ]
          
          列表中的文件都会被TS编译器所编译
      • compilerOptions(重点,以下为compilerOptions的子选项)
        • 编译器的选项
          		{"compilerOptions": {"target": "ES6","module": "system","outDir": "./dist",// "outFile": "./dist/app.js","allowJs": false,"checkJs": false,"removeComments": false,"noEmit": false,"noEmitOnError": true,"strict": true,"alwaysStrict": true,"noImplicitAny": false,"noImplicitThis": true,"strictNullChecks": true} }
          
        • target
          • 用来指定ts被编译为的es版本
          • 可选项:ES3(默认)、ES5、ES6/ES2015、ES7/ES2016、ES2017、ES2018、ES2019、ES2020、ESNext
        • module
          指定要使用的模块化的规范
          'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext', 'node16', 'nodenext'.
          
        • lib
          用来指定所需要的库,一般不用动,有默认值
          可选项:‘es5’, ‘es6’, ‘es2015’, ‘es7’, ‘es2016’, ‘es2017’, ‘es2018’, ‘es2019’, ‘es2020’, ‘es2021’, ‘esnext’, ‘dom’, ‘dom.iterable’, ‘webworker’, ‘webworker.importscripts’, ‘webworker.iterable’, ‘scripthost’, ‘es2015.core’, ‘es2015.collection’, ‘es2015.generator’, ‘es2015.iterable’, ‘es2015.promise’, ‘es2015.proxy’, ‘es2015.reflect’, ‘es2015.symbol’…
          
        • outDir
          • 用来指定编译后文件所在的目录
          "outDir": "./dist"
          
        • outFile
          将代码合并成一个文件,设置outFile后,所有的全局作用域合并在一个文件中,module中只有’amd’‘system’ 支持outFile
          "outFile": "./dist/app.js"
          
        • allowJs
          是否对js文件进行编译,默认是false,如果项目中某些模块用js写,可能需要编译
          "allowJs": false
          
        • checkJs
          检查js是否符合语法规范,默认是false
          "checkJs": false
          
        • removeComments
          是否移除注释,默认是false
          "removeComments": true
          
        • noEmit
          不生成编译后的文件,默认是false
           "noEmit": true
          
        • noEmitOnError
          当有错误时不生成编译后的文件,默认是false
          "noEmitOnError": false
          
        • strict
          所有严格模式的总开关,默认false(配置后相当于以下配置全都开启)
          "strict": true
          
        • alwaysStrict
          用来设置编译后的文件是否适用于严格模式,默认是false
          "alwaysStrict": true
          
        • noImplicitAny
          当某个变量不指定类型时,使用any类型
          "noImplicitAny": true
          
        • noImplicitThis
          不允许类型不明的 this
          "noImplicitThis": true
          
        • strictNullChecks
          严格地检查空值,默认false
          "strictNullChecks": true
          

声明

用关键字class来声明一个类

class Person{...
}

属性

在TS中类的属性一共有三种,在属性面前添加相应的修饰符便可

class Person{name:string = "zhubajie" // 实例属性static age = 89 // 类属性readonly addr:string = "高老庄" // 只读属性
}
  • 实例属性
    直接定义的属性属于实例属性
    他必须通过类实例化之后才能使用
  • 类属性
    static开头的属性为类属性
    他可以通过类直接访问Person.age
  • 只读属性
    readonly定义的属性为只读属性,不可修改
    readonly也可以放再static后面

属性修饰符

pubilc 公共属性,可以再任意位置访问和修改(实例属性,实例化之后访问)
private 私有属性,只能在类的内部进行访问和修改(一般声明的时候我们会以_开头)
protected 受保护的属性,只能在当前类和当前类的子类中进行访问

class Person{public name = "SunWuKong"private age = 30protected sex = "male"
}const person = new Person()
console.log(person.name)
console.log(person.age) // 错误 只能在Person这个类中进行访问
console.log(person.sex)  // 错误 只能在Person这个类和其子类中访问

此外,还有readOnly属性,以他修饰的属性只能读取不能修改

getter 与 setter

  • 类中的每一个属性内置getter方法和setter方法
    getter 方法用于获取属性
    setter 方法用于设置属性
  • 这样,我们可以对属性读取和操作做一些拦截,设置如下
    class Person1{private _name:stringconstructor(name:string){this._name = name;}set name(value:string){this._name = value}get name(){return this._name}
    }
    
    当我们进行读取的时候,其实是走的get这个逻辑
    当我们对于属性进行赋值的时候,其实是走的set这个逻辑

方法

static 静态方法

经过static关键字修饰的方法属于类方法,可以通过类直接使用

class BaJie{name = "BaJie"static age = 18static sayName(){console.log("八戒")}
}// 通过类直接访问
BaJie.sayName()
console.log(BaJie.age);const bajie = new BaJie()
bajie.sayName() // 实例化之后不可访问

当有不规范的语法的时候,ts就不会进行编译,如上面的编译如下

var BaJie = /** @class */ (function () {function BaJie() {this.name = "BaJie";}BaJie.sayName = function () {console.log("八戒");};BaJie.age = 18;return BaJie;
}());
// 通过类直接访问
BaJie.sayName();
console.log(BaJie.age);

实例方法

在类中直接定义的方法为实例方法,没有任何关键字的修饰

这种方法只能在类实例化之后进行使用

class BaJie{name = "BaJie"age = 18sayName(){console.log("八戒")}
}// 通过类直接访问
BaJie.sayName() // 错误的访问方法
console.log(BaJie.age); // 错误的访问方法
// 同样,实例化之后也是可以访问的
const bajie = new BaJie()
bajie.sayName() 
console.log(bajie.name);

构造函数

class Person{name:string;age:nubmer;constructor(name:string,age:number){this.name = namethis.age = age}
}const p1 = new Person('张三',18);
const p2 = new Person('李四',20);console.log(p1);
console.log(p2);

constructor被称为构造函数
构造函数会在对象创建时调用

继承 与 super

// 父类
class Animal{name:string;age: number;constructor(name:string,age:number){this.name = name;this.age = age}sayName(){console.log(this.name)}
}
// 子类
class Dog extends Animal{run(){console.log(`${this.name}run`);}
}
class Cat extends Animal{sayName(){console.log(`我是${this.name}`);}
}
const dog = new Dog("旺财",19)
const cat = new Cat("汤姆",20)
dog.sayName()
dog.run()
cat.sayName()

可以将代码复制到 TypeScript演练场 运行

在这里插入图片描述
我们使用extends关键字来进行继承,其中被继承的Animal为父类,Dog为子类
继承之后,子类会拥有父类的一切属性和方法
子类也可以自己定义一些方法,如上面例子中的run
子类也可以写与父类相同的方法,这样执行方法的时候会执行子类的方法,叫做方法重写Cat类中重写了sayName方法)

抽象类

abstract class Animal{name:string;constructor(name:string){this.name = name;}abstract sayName():void;
}class Dog extends Animal{age:number;constructor(name:string,age:number){super(name);this.age = age;}sayName(): void {console.log(`我是${this.name},我今年${this.age}岁了`);}
}const dog = new Dog("旺财",23)
dog.sayName() // 我是旺财,我今年23岁了

abstract关键字来定义抽象类和抽象方法

  • 抽象类
    抽象类不能用来创建对象
    抽象类只能用于继承(说明类中有哪些属性,哪些方法)
    在抽象类中可以添加抽象方法(如sayName方法)
  • 抽象方法
    抽象方法没有方法体(如sayName方法),且只能定义在抽象类中
    子类必须对于抽象类中的抽象方法进行复写

接口

接口用于描述一个类或者一个对象的结构,描述他们的属性和方法,所以接口可以当做一个类的声明

interface 定义接口

我们使用interface来定义一个接口,定义的方法全部为抽象方法,必须重写

接口用来定义一个类结构,用来定义一个类中应该包含哪些属性和方法

同时接口也可以当成类型声明去使用

interface myInterface{name:string,age:number,sex:"male"|"female",sayName():void
}

implements 使用接口

一般我们使用implements关键字来使用接口

class Person implements myInterface{name: string;age: number;sex: "male" | "female";sayName(): void {console.log(this.name);}
}

多重继承

使用extends来进行接口的继承,且后可以跟多个接口,实现多重继承

interface Obj {[propName:string]:any
}interface myInterface{name:string,age:number
}interface IPerson extends myInterface,Obj{sex:"male"|"female",sayName():void
}class Person implements IPerson{name: string;age: number;sex: "male" | "female";hobby:"read"|"write"sayName(): void {console.log(this.name);}
}

泛型

在指定函数或者类的时候,如果遇到类型不明确的话,就可以使用泛型(不先指定类型,使用的时候进行类型的转换)

一般在声明的变量后面加一个尖括号来声明泛型
在这里插入图片描述
当我们进行类型转换后,编辑器就会有相应的提示

当然我们也可以不指定泛型,ts会进行自动的类型转换

  • 指定多个泛型
    function fn1<T,K>(a:T,b:K):K{console.log(a);return b
    }fn1<number,string>(1,'hello')
    
  • 定义类
    class Person3<T>{name:Tconstructor(name:T){this.name = name}
    }const person4 =  new Person3<string>("Jack")
    console.log(person.name);
    
  • 泛型与接口
    泛型也可以继承接口,使用extends关键字,他表示泛型必须满足接口的条件
    interface IPerson1{name:string,age:number
    }function fn2<T extends NameInterface>(a:T):string{return a.name
    }fn2<IPerson1>({name:"小敏",age:10})
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/460172.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【RT-DETR进阶实战】利用RT-DETR进行视频划定区域目标统计计数

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 Hello,各位读者,最近会给大家发一些进阶实战的讲解,如何利用RT-DETR现有的一些功能进行一些实战, 让我们不仅会改进RT-DETR,也能够利用RT-DETR去做一些简单的小工作,后面我也会将这些功能利用PyQt或者是…

HarmonyOS 创建components目录 定义全局自定义组件导出供整个项目使用

之前我的文章 harmonyOS 自定义组件基础演示讲解 我们讲解了 自定义组件的基础用法 但是 我们是写在单个page文件中的 这样 我们跨文件使用就很不友好了 如下图 指向 ets目录下 创建一个目录 按我们 前端开发以往的习惯 这个目录要叫 components 专门放组件集合的地方 然后 按…

macbook电脑如何永久删除app软件?

在使用MacBook的过程中&#xff0c;我们经常会下载各种App来满足日常的工作和娱乐需求。然而&#xff0c;随着时间的积累&#xff0c;这些App不仅占据了宝贵的硬盘空间&#xff0c;还可能拖慢电脑的运行速度。那么&#xff0c;如何有效地管理和删除这些不再需要的App呢&#xf…

Unity BuffSystem buff系统

Unity BuffSystem buff系统 一、介绍二、buff系统架构三、架构讲解四、框架使用buff数据Json数据以及工具ShowTypeBuffTypeMountTypeBuffOverlapBuffShutDownTypeBuffCalculateType时间和层数这里也不过多说明了如何给生物添加buff 五、总结 一、介绍 现在基本做游戏都会需要些…

Gitlab和Jenkins集成 实现CI (二)

配置Gitlab api token 配置 Gitlab 进入gitlab #mermaid-svg-QQWExcx5fpZ59Sk7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#000000;}#mermaid-svg-QQWExcx5fpZ59Sk7 .error-icon{fill:#552222;}#mermaid-svg-QQWExcx5fpZ59Sk7 .e…

微信小程序(三十九)表单信息收集

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.表单收集的基本方法 2.picker的不足及解决方法 源码&#xff1a; index.wxml <!-- 用户信息 --> <view class"register"><!-- 绑定表单信息收集事件--><form bindsubmit"…

Linux下的多线程

前面学习了进程、文件等概念&#xff0c;接下里为大家引入线程的概念 多线程 线程是什么&#xff1f;为什么要有线程&#xff1f;线程的优缺点Linux线程操作线程创建线程等待线程终止线程分离 线程间的私有和共享数据理解线程库和线程id深刻理解Linux多线程&#xff08;重点&a…

AI大模型开发架构设计(9)——AI 编程架构刨析和业务应用实战案例

文章目录 AI 编程架构刨析和业务应用实战案例1 AI编程代码生成模型剖析编程方式的发展代码自动生成基于大模型的AI编程工具——Github Copilot以 CodeGeeX 为例-发展过程以 CodeGeeX 为例-训练过程以 CodeGeeX 为例-大规模代码数据处理以 CodeGeeX 为例-模型结构以 CodeGeeX 为…

【开源】基于JAVA+Vue+SpringBoot的新能源电池回收系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户档案模块2.2 电池品类模块2.3 回收机构模块2.4 电池订单模块2.5 客服咨询模块 三、系统设计3.1 用例设计3.2 业务流程设计3.3 E-R 图设计 四、系统展示五、核心代码5.1 增改电池类型5.2 查询电池品类5.3 查询电池回…

this指针剖析

this指针 this指针引出&#x1f4a6;特性&#x1f4a6;this指针存储位置 this指针 引出&#x1f4a6; 我们先来定义一个日期类 Date class Date { public: void Init(int year, int month, int day) { _year year; _month month; _day day; } void Print() { cout <<…

spring Bean 生命周期 源代码分析

文章目录 一、生命周期关键步骤1.1 前置条件1.2 创建bean 二、Bean生命周期、核心源码分析2.1 前置条件, 源代码2.2 创建bean, 源代码 一、生命周期关键步骤 1.1 前置条件 1.创建rootBean 生成RootBeanDefinition 2.对bean定义的方法&#xff0c;进行验证、重写 调用方法pre…

5G NR 频率计算

5G中引入了频率栅格的概念&#xff0c;也就是小区中心频点和SSB的频域位置不能随意配置&#xff0c;必须满足一定规律&#xff0c;主要目的是为了UE能快速的搜索小区&#xff1b;其中三个最重要的概念是Channel raster 、synchronization raster和pointA。 1、Channel raster …