♠♦♣TypeScript


Do you like studying?

TypeScript 介绍

JS的类型系统存在 ‘先天缺陷’,JS代码中绝大部分都是类型错误
增加了找 BUG 改 Bug 时间影响开发效率

从编程语言分析 TypeScript 属于静态类型编程语言, JavaScript 属于动态类型编程语言
静态类型:编译期类型检查:动态类型:执行期做类型检查
代码编译和代码编译代码执行顺序:1编译 2执行

JS 需要等到代码真正取 执行才会发现错误(晚)
TS 在代码编译的时候(代码执行前)发现错误
并且 配合 VSCode 等开发工具,TS 可以 提前在编译代码的同时就发现代码中的错误,减少找 BUg 改Bug 时间

  1. TypeScript 相比 JS优势
  • TS相比JS写代码更早发现错误减少改BUG 找Bug时间提高开发效率
  • 编程任何位置代码都有 代码提示随时随地的安全感,增强了开发体验
  • 强大的类型系统提升了代码可维护性,是的 重构代码更加容易
  • 支持最新 ECMAScript语法,优先体验罪行语法,让你走在前端技术最前沿。
  • TS类型推断机制,不需要在代码中的每个地方都显示标注类型让你在享受优势同时,尽量降低成本

Vue3 源代码使用 TS 重写,Angular 默认支持 TS, React 与 TS 完美配合, TypeScript 已成为大中型前端项目首选编程语言

VsCode 开发环境

VsCode官网下载
node.js

TypeScript

TypeScript入门教程
TypeScript

在这里插入图片描述
安装步骤 :

  • 打开 VSCode 终端
  • 输入安装命令: npm i -g typescript 回车,来安装(注意联网 全局安装)全局安装 。Users\xxx> 输入命令
    typescript 就是用来解析 TS 工具包 提供了 tsc 命令,实现了 TS -> JS变化npm: 是安装node环境依赖命令 i (install)表示安装, -g(–global) 全局标识 可以在任意目录使用该工具
# 安装命令
npm install typescript -g
# 查看版本
tsc --version

在这里插入图片描述

npm install ts-node -g
npm install tslib @types/node -g
ts-node math.ts

在这里插入图片描述
在这里插入图片描述
能够掌握变量基本使用 理解类型注释作用 说出变量名规范 基本数据类型
1.什么是变量
变量 用来存储数据的容器 并且发生变化
2.基本使用
变量的使用分为两部: 声明变量并且指定类型给变量赋值
第一步:指定变量的类型

let age: number;
解析:

  • let是TS声明变量关键字
  • age 是程序员自己定义变量的名称
  • number 给age变量指定数值类型
var/let/const 标识符: 数据类型 = 赋值;
console.log('前端攻城狮')
var message: string = '剑来'
console.log(message)
message = '一剑开天门'
console.log(message)
let age: number = 26
console.log(age)
let sum:number = 27
console.log(sum)

变量命名规范

  • 变量名称只能出现: 数字,字母,下划线(_), $, 并且不能以数字 开头。
let age:number = 26;

let 2h //不合法
let $name //正确
let first_name //正确
let @namil //错误

  • 注意: 变量名称区分大小写
//Num num 是两个不同的变量
let Num:number = 28
console.log(Num)
let num:number = 29
console.log(num)

变量名称规范

  • 代码 规范让人觉得 更简洁 专业 优雅
  • 推荐: 变量名称要有意义,顾名思义
  • 推荐: 使用驼峰命名(首字母小写 后面每个单词字母大写)
let cityName
let youAge

数据类型概述
网页中有什么内容 文字 图片 视频 音乐
计算机可以正确处理这些内容如何区分不同内容
常用基础类型
可以将 JS 中的常用基础类型细分两种 1JS已有类型 2TS新增类型

JS已有类型

  • 原始类型 number string boolean null undefind symbol
  • 对象类型 object (数组,对象,函数对象)

TS新增类型

  • 联合类型,自定义类型(类型别名),接口,元组,字面量类型,枚举,void any等
    数据类型
  • TypeScript 存储量大类 1.原始类型 基本数据类型 ,2.对象类型 (复杂数据类型)
  • 常用基本数据类型5个: Number string boolean undefined null

变量 age 类型是 number 数字

let age:number = 26

‘Hello Ts’ 是 string 字符串

console.log('Hello TS')
基本数据类型
数字类型
  • 数字类型: 包涵整点 浮点 整点就是整数 浮点带小数点值
//整点
let age: number = 26
//浮点
let Age: number = 26.6
  • 正数 负数
//正数会省略+号
let salary:number = +1000
//负数
let salaryWithGirLfriend: number = -2000
  • 数字类型是我们开发中经常使用的类型,TypeScript和JavaScript一样,不区分整数类型(int)和浮点型(double),统一为number类型。
  • 如果你学习过ES6应该知道,ES6新增了二进制和八进制的表示方法,而TypeScript也是支持二进制、八进制、十六进制的表示:
let num1: number = 100 // 十进制
let num2: number = 0b100 // 二级制
let num3: number = 0o100 // 八进制
let num4: number = 0x100 // 十六进制
console.log(num1, num2, num3, num4) // 100 4 64 256
字符串
  • 字符串:是由零或多个字符串连而成用来表示文本信息
  • 字符串可以使用 单引号'' 双引号""
  • 同时也支持ES6的模板字符串来拼接变量和字符串
let str:string = 'Hellword'
let sty:string = "Hellword TS"
//ES6 模板字符串 拼接
const name = '海蒂拉玛'
const age = 19
const height = 1.74
const message = `千秋无绝色悦目是佳人,倾国倾城貌惊为天下人 name:${name} 身高:${height}:${age}`
console.log(str,sty)
console.log(message)
null undefined
const n1: null = null
const n2: undefined = undefined
  • 在 JavaScript 中,undefined 和 null 是两个基本数据类型。
  • 在TypeScript中,它们各自的类型也是undefined和null,也就意味着它们既是实际的值,也是自己的类型
  • undefined : 声明未赋值变量值
  • null : 声明变量已赋值 ,为 null
运算符

+ 号作用

  • 如果 字符串和数字拼接是字符串
  • +号作用 两两相加 字符串拼接
console.log(1+2)// 3
console.log(1+'2'+0)//120
console.log('7'+2)//72
console.log(1+9+'8')//108

加号引发的思考

console.log(2 - '1')// 会报错 算数运算符必须是字符串数字类型
  • 如果我们在工作中遇到 数字 - 字符串 除了+号以外其他算数运算符应该跟其他类型一起使用
console.log(2 - +'1')//1
let age:number = +'26'//age是一个number 赋值 是字符串 在字符串前面+号转化为数字类型
console.log(age,typeof(age))
  • 将字符串类型转换 数字类型
  • +1 表示 ‘1’(string) => 1(number)
  • 所以 2 - +‘1’ ==> 2 - 1 ==>结果 1
  • 字符串前面+号 可以将 string 转化为 number (字符串内容为数字类型才用意义)

= 赋值

  • 把右边的变量给到左边 =
let age: number = 25
console.log(age)//25
age = age + 1
console.log(age)//26

+=, -= ,*= ,/=, 先赋值在计算
++ –

  • ++ +1 – -1
let age:number = +'26'
++age //先加 +1
console.log(age)
age-- //后减 -1
console.log(age)

比较运算符

console.log(1>2)//false  结果为boolear true或false
console.log(3>=2)// 3大于等于2吗? 是的 true
console.log(1<2)//1<2吗?是的结果为 true
console.log(3<=2)//false
console.log(3<=100)//true
let sum1:number = 3
let sum2:number = 4
console.log(sum1 !== sum2)//true 3 是否不等于 4
console.log(sum1 === sum2)//false 他们的值是否相等 不相等

逻辑运算符

  • 生活中: 并且 或者 不是这样的词语,来解释事情。
    1. 有钱 并且漂亮
    2. 有钱或者漂亮
    3. 不是 (取反)
  • 逻辑运算符——对应 并且,或者,不是,逻辑运算符用于布尔类型计算,并且结果也是布尔类型
  • 与(逻辑与),用 &&符号来表示。两边的值同时为true,结果为true;否则为 false。
console.log(true && false)//false
console.log(1<2 && 3>=2)//true
console.log(2<19 && 58>=77)//false
  • 逻辑或 ||符号表示当两边值只要有一个为true结果就是 true 否则为 false。
console.log(true || false)//true
console.log(false || true)//true
console.log(true || true)//true
console.log(false || false)//false
console.log(29>=29.1 || 46 >= 45.9)//true 
  • 非(逻辑非) ! 表示取反即: true → false 而 false → true
console.log(!true)//false
console.log(!false)//true
console.log(!false || false)//true
条件语句
  • 举个例子我们观看异步电影需要VIP会员才能看完整版,否则只能看前5分钟
  • 条件语句:根据判断条件 (真假),来执行不同的代码从而实现不同功能
  1. 如果条件满足 就执行1
  2. 如果条件满足就执行2
  3. 如果以上两个条件都不满足就执行 else 结束。

if语句

if (条件判断){
条件满足
}

else 语句

  • 在TypeScript中 else 语句必须配合if语句使用else表示条件不满足要做的事情
  • else语句
  • 判断条件:是否满足两个条件其中一个 布尔值类型

let isVip:boolean = false //boolean值 true false
if(isVip){//判断条件
console.log(‘满足条件’)//true
} else {
console.log(‘不满足条件’)//false
}

三元运算符

  • 三运算符类似 if … else语句
  • 作用 根据判断条件真假 得到不同结果
    语法:

结果 = 判断条件 ? 1值 : 2值

  1. 如果判断条件为真, 执行值1
  2. 否则,判断条件为假,执行值2
let str:string = 5 < 3 ? '大于' : '小于'
console.log(str)

结果类型值1值2类型决定

let Age:number = 27
let sum:string = Age < 20 ? '犬夜叉' : '王者荣耀'
console.log(sum)
循环语句
  • for循环语句组成:
    1. 初始化 : 声明计数器变量用来记录循环次数(执行一次)。
    2. 判断条件: 判断循环次数是否达到目标次数。
    3. 计数器更新: 完成一次循环计数器+1
    4. 循环体:循环的代码,也是重复做的事情

for (初始化语句;判断条件;计数器更新) {
循环体
}

for(let a = 1; a <= 3; a++){
    console.log('保持警觉意味着“严肃认真”,“严肃认真”意味着虔诚和真实,只有保持真诚,才能达到“与道为一”的境界')
}
for(let a :number = 1; a <= 3; a++){
    console.log('专心致志地做一件事,就像此刻没有任何特殊的事情发生。')
}

for 循环语句执行的过程

初始化计数器 (1 = 1) 只执行一次 初始化

  1. a 判断 (1 <= 3) b 循环代码 打印 c 计数器++(i变为2)
  2. a 判断 (2 <= 3) b 循环代码 打印 c 计数器++(i变为3)
  3. a 判断 (3 <= 3) b 循环代码 打印 c 计数器++(i变为4)
  4. a 判断条件(4<=3),条件不满足,循环结束
  • 每吃一次包子打印一次
for(let a :number = 1; a <= 3; a++){
    console.log('正在吃第'+ a +'个包子')
}
  • 1-100计算所有值的和
let sum:number = 1//定义一个初始值让他的值每次相加+1
for(let a:number = 1; a <= 100; a++){//循环1——100
    sum += a  //sum每次+1
}
    console.log(sum)//在外面输出最后一次结果就可以了

break

  • break 结束本次循环
for(let a:number = 1; a <= 4; a++){//他循环四次执行输出四次
    if(a === 4){//我们判断他的值等于4
        break//结束
    }
    console.log('我吃了'+a+'包子')//结果输出三次
}

continue

  • 跳过本次循环执行下次循环
for(let a:number = 1; a <= 4; a++){//他循环四次执行输出四次
    if(a === 3){//我们判断他的值等于4
        continue//中断跳过本次执行下次
    }
    console.log('我吃了'+a+'包子')//结果输出第四次少输出第三次
}
VSCode断点调试
  1. 准备要调试的 TS文件新建a.ts文件夹,作为要调试的 ts 文件
console.log('北冥有鱼其名为鲲,鲲之大一锅装不下')
for(let i: number = 1; i <= 3; i++){
    console.log('北冥有鱼其名为鲲,鲲之大一锅装不下')
}
  1. 添加调试配置
    VSCode左侧菜单栏调试运行点击 生成默认配置 launch.json文件 修改配置:
{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "调试TS",
            "runtimeArgs": [
                "-r","ts-node/register"
            ],
            "args": ["${workspaceFolder}/a.ts"]
        }
    ]
}
  1. 安装下载依赖包

add,i(下载)-g(全局)
下载命令:
npm i ts-node typescript
cnpm i ts-node typescript
yarn add ts-node typescript

  1. 调试
  1. 查看 console.log() (控制台输出)
  2. 监视变量值 (鼠标移入添加左侧监视窗口)
  3. 点击 断点
数组
  • 如果我们有个字符串命名

let HowardHughes:string = ‘霍华德修斯’

  • 如果我们有四个多个N个

let HedyLamarr:string = ‘海蒂拉玛’
let JanePeters:string = ‘简皮特斯’
let katharinehepburn:string = ‘凯瑟琳赫本’
let RitaHayworth:string = ‘丽塔海华丝’

  • 这时候就用到我们数组了
let name:string[] = ['霍华德修斯','海蒂拉玛','简皮特斯','凯瑟琳赫本','丽塔海华丝','伊丽莎白泰勒']
  • 数组中声明的都是同一类型的值

let names: string[] = []
[]中括号表示数组如果数组没有内容就是一个空数组

创建数组两种语法形式

let name :string[] = []
  • 创建数组语法两种
  • [] 表示数组 如果数组中没有内容它是一个空数组。
    数组类型注解两部分类型+[]。字符串数组。
let name:string[] = ['霍华德修斯','海蒂拉玛','简皮特斯','凯瑟琳赫本','丽塔海华丝','伊丽莎白泰勒']
  • 数组多个元素组成逗号,分隔数组中的每一项内容称为元素

创建数组

  • 创建数组两种方式

let name: string[] = new Array()
[]相同但是更加繁琐
数组中数据
let name: string[] = new Array(‘简皮特斯’,‘凯瑟琳赫本’,‘丽塔海华丝’)
相当于
let names:string = [‘霍华德修斯’,‘海蒂拉玛’,‘简皮特斯’,‘凯瑟琳赫本’,‘丽塔海华丝’,‘伊丽莎白泰勒’]

数组长度 length
1.获取数组长度我们用length它返回的就是数组长度的总和
2.index获取的则是数组的下标它是以0开头然后进行输出的,所以我们的下标比数组长度length少一位length -1

let newArray: number[] = new Array(1,2,3,5,6)
console.log(newArray,newArray.length)

取值

  1. 数组取值可以通过下标当前项来取到单个数组里面的值内容index下标是从0,1,2,3,4,5开始的
let newArray: number[] = new Array(1,2,3,5,6)
console.log(newArray,newArray.length)
console.log(newArray[1])//2
console.log(newArray[2])//3
console.log(newArray[3])//4

存值

  • 数组名称[索引] = 新值,根据索引是否存在,有两种功能1.修改元素 2.添加元素

let foods: string[] = [‘白垩纪’,‘侏罗纪’,]
//数组索引分别是 0 1

  • 如果索引存在,表示修改元素

foods[1] =[‘白垩纪’]

  • 如果索引不存在,就表示添加元素
let mobilephone:string[] = ['苹果','华为','三星']
console.log(mobilephone[1],mobilephone[3])//华为 undefined
// 我们如何把值存储到数组里面呢?可以用下标,length
  mobilephone[2] = 'xxx'
  console.log(mobilephone)
  mobilephone[3] = '小米'
console.log(mobilephone)//值就存进去了并返回新的数组长度

如果index索引不存在可以添加元素
遍历数组
2. 遍历数组也就是一次获取数组中的元素并且逐个获取一次。

let nums: number[] = [100,200,300]
//索引 0 1 2

  1. 使用for循环遍历数组
for (let a = 0; a <= arr.length; a++){
	console.log(arr[i])
}
  1. 因为数组索引是0开始计数器a默认值为0
  2. 应该根据数组长度来计算,公式数组长度-1,就是我们的nums:length -1(最大索引) length数组长度一词根据数组的长度变化

数组不等于 0

//找出数组不为0的元素放到一个新数组中
let nums1:number[] = [1,2,3,4,5,6,53,-1,2000,-22,0]
//我们创建一个新数组 用来存储新的值
let newArr: number[] = []
//使用for循环遍历数组拿到数组item
for(let a:number = 1; a <= nums1.length; a++){//循环遍历当前数组中的每一项
    if(nums1[a] !== 0){//判断我们循环遍历的当前 数组里面的item 不等于 0
        newArr[newArr.length] = nums1[a];//进行一个赋值到我们上面新添加的数组中去
    }
}
console.log(newArr)//在外面我们就拿到了新数组中的值
  1. 数组去重
    set()
let numnum: number[] = [1,2,3,4,5,6,1,2,3,5,1,2,3,5,5,6]
function getnum(num:number[]){
  return [...new Set(num)]
}
console.log(getnum(numnum))

indexOf()
查询返回下标(index隐式转换)数组循环一遍有返回下标没有返回-1

function getsum(num:number[]){
    let sum : number[] = []
    for(let a :number = 0; a < num.length; a++){
        if(sum.indexOf(num[a]) == -1){
            sum.push(num[a])
        }
    }
    return sum
}
console.log(getsum(numnum))

forEach,indexOf

function getsum(num:number[]){
    let sum:number[] = []
    num.forEach(function(item){
        if(sum.indexOf(num[item]) == -1){
            sum.push(num[item])
        }
    })
}
console.log(getnum(numnum))

利用数组原型对象上的includes方法

function getnums(num:number[]){
    let sum:number[] = []
    num.forEach(function(item){
        if(!sum.includes(num[item])){
            sum.push(num[item])
        }
    })
    return sum
}
console.log(getnums(numnum))
function getf(num:number[]){
    let sum:number[] = []
    num.forEach(function(item){
        return sum.includes(item) ? '' : sum.push(item)
    })
    return sum
}
console.log(getf(numnum))

filter

function getf(num:number[]){
    let sum:number[] = []
    sum = num.filter(function(item){
        return sum.includes(item) ? '' : sum.push(item)
    })
    return sum
}
console.log(getf(numnum))

filter数组去空

 var arr = ['A', '', 'B', null, undefined, 'C', '  '];
    var r = arr.filter((s) => {
    return s && s.trim();     // 注:IE9(不包含IE9)以下的版本没有trim()方法
    });
    console.log(r);
联合类型

多个类型的集合在TS中叫做联合类型(由两个或多个其他类型组成类型,表示可以是这些类型中的任意一种元素类型) ( | )用分隔开

let strnum:(string|number)[] = [1,2,4,'古','今']
console.log(strnum)
let nubsn:(null|undefined|string|number|boolean)[] = [null, ' ', 'string',95,true,false,undefined,0]
console.log(nubsn)

类型别名
(自定义类型)为任意类型起别名
使用场景:同一(复杂)被多次使用,通过类型别名,简化该类型使用

  • 使用type关键字;来创建类型别名。
  • 类型别名可以是任意合法变量名称
  • 创建乐行别名后,直接使用该类型别名作为变量名称作为类型注解
type CustomArray = (null|undefined|string)[]
let ayy:CustomArray = ['1',' ', undefined]
console.log(ayy)
元组

场景: 在地图中,使用经纬坐标标记位置信息
可以使用数组来记录标记,那么,该数组中只有两个元素,并且都是数值类型

let position: number[] = [11.65,34.12,0]

使用**number[ ]**的缺点:不严谨,因为该类型数组中可以出现任意多个数字
元组 (Tuple)
元组类型是另一种类型数组它,确切地知道多少个元素,以及特定对应的类型

let positions: [number,number] = [1.2,1.3]
console.log(positions)
let psositionsn: [number,string] = [1,'二']
console.log(psositionsn)
function

函数复用

function getSum(nums: number[]) {
  let num: number = 0;
  for (let a: number = 0; a <= nums2.length - 1; a++) {
    num = num + nums2[a];
  }
  console.log(num);
}
let nums2: number[] = [5, 10, 80];
getSum(nums2)
let nums:number[] = [5,6,7,8]
getSum(nums)

所谓函数,就是声明一次可以调用任意多次一段代码
意义: 代码实现了 复用 提高开发效率

函数使用
函数的使用分为两步 1.声明函数 2.调用函数(类比变量)

  1. 声明函数
function 函数名(){
    函数体
}
函数名()

函数名称: 推荐以动词开头,因为函数表示做一件事,实现一个功能
函数体: 表示实现功能代码,复用代码

  1. 调用函数

函数名()
比如: sing()
只有调用函数,代码才会执行

  1. 函数使用
    创建一个函数 求两个number类型数值和
function term(){
    let num1:number = 1;
    let num3:number = 2;
    let result = num1 + num3
    console.log(result)
}
term()
  1. 函数参数
function sting(songName:string){
  console.log(songName)
}
sting('我本桀骜少年臣不信鬼神,不信人!演唱')
sting('让酒,姜姜')
sting('->')

函数参数的作用:增加函数灵活性,通用性针对相同功能,能够适应更多的数据(值)

同时指定函数参数返回值类型

const add = (num1:number,num2:number) => {
  return num1 + num2
}
console.log(add(90,5))
  1. 形参实参

形参function 函数名(形参) ,声明变量的占位符并没有赋值

function sing(songName: string){}

作用: 指定函数可接收数据
实参调用函数名(实参),给声明变量占位符赋值

sing('让酒,姜姜')

形参 指定函数能接收数据
实参 是一个具体的值用来赋值给参数

void
如果函数没有返回值函数返回值是 void

let strname:string = '情绪猿'
function greet(name: string): void{
    console.log('hello wrold'+name)
}
greet(strname)
  1. 参数和参数之间 逗号 , 分隔 ,在TS里必须指定参数的 类型
function fn(name:string,age:number){
  console.log(name,age)
}
fn('梨',1)

形参name:string,字符串类型 age:number数字类型, 实参 ‘梨’,1
函数名()里的形参数量,和调用函数名()实参对应,类型也必须相对应

封装一个 function 计算 任意两个数值的和

function sum(num1:number,num2:number){
   let result = num1 + num2;
   console.log(result)
}
sum(10,2)

封装一个 function 计算 任意数组的和

function gesum(sum: number[]){//传入一个数组参数
  let yum: number = 0;//计算和  初始值 0
  for(let a: number = 0; a <= sum.length -1; a++){
    yum += sum[a]//循环数组每一项并赋值
  }
  console.log(yum)
}
gesum([1,2,3,4])//调用函数名并传入 任意 数组 
gesum([10,70,9,6])
  1. 函数返回值
    函数返回值的作用: 将函数内部计算结果返回,以便于使用该结果继续参与其他计算。
    计算以下两次调用结果的和。
gesum([1,2,3,4]) //10
gesum([10,70,9,6]) //95
gesum([1,2,3,4]) + gesum([10,70,9,6])//10 + 95 = 105

关键点 拿到函数(gesum) 内部计算结果 然后,才进行后续加法计算。
注意: 如果没有指定函数返回值,那么 函数返回值默认类型void 空

function gesum(sum: number[]):number{//给它指定 number类型
  let yum: number = 0;
  for(let a: number = 0; a <= sum.length -1; a++){
    yum += sum[a]//循环数组每一项并赋值
  }
  return yum //返回值 返回数组的和
}
 let rest = gesum([1,2,3,4]) +gesum([10,70,9,6])//两个数组计算  
 console.log(rest)

使用返回值returnfunction内部值再次计算,如果函数不再进行计算用不到 返回值return

  1. 返回值
    1.指定返回值类型 2.指定返回值

function fn(): 类型注解{
reuturn 返回值
}

在函数体中 使用 return 关键字来返回函数执行结果

function fn():number{
return 18
}

返回值一定要符合类型要求

函数返回值两种使用方法

 function tu():number{//定义函数返回值 number类型
    return 25 //返回 number类型
 }
 let res:number = tu() //函数返回值 赋值 
 let res:number = fn()// 相当于
console.log(res)
console.log(res+1)//对函数进行一个 运算 
console.log(tu()/2)

赋值使用
let res:number = tu() //函数返回值 赋值
let res:number = fn()// 相当于
console.log(res)
调用函数使用
console.log(tu()/2)

  1. 封装(clacArea)计算任意三角形面积并返回

公式 1/2 * 底 * 高 / 2

function clacArea(a:number,h:number):number{
    // let area:number = 1/2 * a * h// 简化一下 直接返回 公式不用返回得出的值
    return 1/2 * a * h
}
console.log(clacArea(10,10))//再传入相对应的值
console.log(clacArea(2,60))//根据不同的值得到的结果也不同

封装函数(getMax),得到两个数最大值并返回

function getMax(num1:number,num2:number):number{
     return num1 > num2 ? num1 : num2
}
console.log(getMax(1,2))
console.log(getMax(200,100))
console.log(getMax(-1000,1))
  1. return 讲解
    return function返回,终止函数执行
//去网吧上网function 是否满18
	function play(age:number):void{
	    if(age < 18){
	     return 
	    }
	    console.log('欢迎上网')
	}
	play(1)
	play(18)
	play(19)

函数没有返回值,默认返回值类型 void

函数可选可不选参数

再给函数指定类型时,就用到可选参数
比如数组 slice 方法

function mySlice(start?:number,end?:number): void{
  console.log('起始',start,'结束值',end)
}
mySlice()
mySlice(1)
mySlice(1,2)

可选参数后面添加? :之前
可选参数只能出现在参数列表最后,也就是说可选参数后面不能再出现必选参数
可以第一个参数 为必选参数 第二个参数后面的参数为 可选参数调用函数实参必传不然报错

  1. 断点调试
    借助断点调试观察代码执行过程
    1.在哪个位置打断点? 2.如何调试?
    断点位置: 函数调试所在位置
    ↓ 单步调试执行一行代码,遇到函数调用时,进入函数内部
    ↑ 单步跳出 跳出当前函数(函数代码执行完成)
变量作用域

一个变量作用域是:代码中定义的区域,他决定了变量适用范围
在 TS JS ,函数可以形成作用域,函数作用域
变量可以分为两种 1全局变量 2局部变量

  1. 局部变量只在函数内部声明的变量,该变量只能在函数内部使用
	function fn(){//function 内部声明一个变量是函数私有的变量
	    let num: number = 1;
	    console.log(num)//只有函数自身能访问
	}
	fn()
	//在外部访问会报错 undefind 
	console.log(num)
  1. 全局变量在函数外面全局状态下声明在任何函数里都可以访问全局变量
	let yum:string = '和'//在函数外面那全局声明的变量称之为全局变量
	function fn1(){//function里面 访问
	    console.log(yum)// 和  可以访问到
	}
	fn1()
Object类型

对象:一组相关属性和方法的集合,无序的
TS中 如果要描述一个事物一组相关数据,可以使用对象

let person = {}

此处{ }(花括号,大括号)表示对象。而对象没有属性或方法,称: 空对象
对象中的属性或方法,才用键值对的形式, 键 , 值之间用 : 来配对

let person = {
name: ‘刘老师’,
age: 25
}
(key)→ 名称,(value)→ 具体内容

对象可以是属性方法组成
属性和方法的区别:值是不是函数如果是,就称为方法;如果不是 就是普通方法

let person = {
sayHi: function () { console.log('hello wlod') }
}
注意:函数作用方法时可以省略function后面函数名称,也叫做 匿名函数
函数没有名称如何调用? sayHi相当于函数名称,将来通过对象的 sayHi 就可以调用
如果一个函数是单独出现的,没有与对象关联,我们称为函数否则;称为方法

  1. 接口
    TS中的对象是结构化的,结构简单来说就是对象有什么属性或方法
    在使用对象前,就可以根据要求提前设计好对象的结构。
    比如:创建一个对象,包含姓名, 年龄 两个属性
    思考过程:1.对象包含结构姓名,年龄 两个属性,2.姓名→字符串,年龄→数字, 3,创建对象
	let person = {
	    name:'袁天罡',
	    age: 25,
	}

建立一种对象的语法约束
键值对中的值是类型(因为这是对象的类型注解)
多个键值对之间 ; 分隔并且分号可省略

类型注解 {} 表示对象的类型注解
let persone : {
    name: string;
    age: number;
}
类型赋值  此处{} 表示ts中的对象
persone = {
    name: '征服者',
    age:25
}
  1. 对象方法的类型注解
    如何给对象中的方法添加类型注解,类型注解?
    技巧 鼠标放到 变量名上 VSCocde就会给出变量类型注解。
let person : {
sayHi: () => void
sing: (name:string) => void
sum: (num1: number, num2: number) => number
}

箭头 =>左边 小括号内容表示参数类型
箭头 => 右边内容 表示返回值类型
方法类型注解关键点: 1参数 , 2返回值

let age = 26
let songName = '下雨'
let isVip = true
let pers = {
    name : '高中老师',
    age : 22
}
let p1:{
    sayHi:() => void
}
 p1 = {
    sayHi: function(){
        console.log('晚风心里吹')
    }
}
let p2 : {
    sing (name:string) : void
}
 p2 = {
    sing: function(name:string){
        console.log('不甘')
    }
}
let p3 :{
    sum(num1:number,num2:number) : number
}
 p3 = {
    sum: function(num1: number,num2: number) {
        return num1 + num2
    }
}
  1. 接口
    创建接口对对象进行类型注解 规定接口 键值对 类型 约束 创建接口的关键字 interface
创建接口 规定接口 键值对 类型 约束
interface IUser {
    name: string
    age: number
    sayHi: () => void
}
使用接口 复用
let p1: IUser = {
    name:'画江湖',
    age:10,
    sayHi: function(){
        console.log('若森数字出品')
    }
}
let p2: IUser = {
    name:'少年歌行',
    age:4,
    sayHi: function(){
        console.log('周木楠著作')
    }
}

类型别名
interface(接口) type(类型别名)

  • 相同点都是给对象指定类型
  • 不同 接口只能为对象指定类型
  • 类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名
type Ipt = {
    name:string
    age:number
    SayHi(): void
}
let pers: Ipt = {
    name:'Holl',
    age:1,
    SayHi(){
        console.log('wrold')
    }
}
接口继承
  1. 存值取值
 interface Hret {
    name:string
    height : number
    sum: () => void
}

 let jay: Hret = {
    name:'Hret',
    height:1,
    sum: function(){
        let to :string= '贝拉贝拉';
        console.log(to)
    }
 }
 // 通过 . 方法取到对象中的值
 console.log(jay.name,jay.height)
 //调用方法
 jay.sum()
 jay.name = 'king'
 jay.height = 18
 console.log(jay.name,jay.height)

通过 . 方法取到对象中的值
对象: 1.属性 2.方法
对象就是无需键值对的集合
使用接口作为对象的类型注解,建立约束对象的结构
TS中数据类型分为两大类 1原始类型(基本数据类型) 2对象类型(复杂数据类型)
常用的基本数据类型有5个: number string boolean undefind null
复杂数据类型 object (对象 数组) function (函数)

内置对象

对象的两种 1自己创建 2其他人创建 编程语言自带或第三方)
内置对象: TS JS 自带了一些基础对象提供了TS开发时所需的基础或必要能力。

查文档

编程不是死记硬背,而是掌握一定技巧,查文档就是最重要的一个
文档 : MDNw3school

  1. push
    数组内置函数尾部添加添加与数组子类型一致
let songs: string[] = ['晚风心里吹','不甘','SeeYouAgin']
songs.length
//length 属性
songs.push('一笑江湖')
console.log(songs,songs.length)

push 添加常量 cosnt

const strp:number[] = [12,0,5,95]
//const 常量声明 不能添加会报错 重新赋值数组名添加
let newStrp = strp
newStrp.push(7)
console.log(newStrp)
  1. forEach
songs.forEach(function(item,index){
    console.log('索引',index,'元素',item)
})

模拟forEach

//模拟forEach 函数是实参
function forEach1(callbackfn: (value: string, index: number)=>void){}
//模拟 forEach 方法调用   此处函数是实参
forEach1(function(value,index){})

forEach 返回值是一个匿名函数 两个参数 index 下标 item每一项 参数值类型不固定根据循环数组类型变化

let songs: string[] = ['晚风心里吹','不甘','SeeYouAgin']
let sums:number[] = [1,2,3]
sums.forEach(function(value,index){console.log(value,index)})
songs.forEach(function(item){console.log(item)})

两个参数 参数名不固定随意也可以省略只写一个参数

  1. some
    some方法:遍历数组,查找是否有一个满足条件的元素(如果有,停止循环)
    循环特点:根据回调函数返回值,决定是否停止循环。返回 true 停止,返回 false 继续循环
let num1 :number[] = [1,2,3,-11]
let hae: boolean = num1.some(function(num){
    if(num > 10){
        return true
    }
    return false 
})
console.log(hae)

some 方法返回值boolean 如果找到满足返回 true 停止,返回 false 继续循环

类型推论

在TS中某些没哟明确指出类型的地方,类型推论会帮助提供类型。
由于类型推论的存在,这些地方,类型注解可以省略
发生类型推论2种常见场景: 1声明变量初始化 2决定函数返回值

let age: number = 18 → let age = 18
function sum(num1:number,num2:number):number{return num1+num2}→funtion sum(num1:number,num2:number){ return num1 + num2}

这两种情况下,类型注解可以不写!
能写类型注解的地方,就省略(葱粉利用TS类型推论能力,提高开发效率)。
培养建立类型思维

对象可选属性

对象的属性或方法也是可选 此时及用到可选属性
比如:使用axios({…})时,如果发送 GET请求,methods属性就可以省略

function myAxios(config: {url:string,methods?:string}){}
myAxios({
    url:''
})

可选属性语法与函数可选参数的语法一致,都可以使用?表示

接口继承

如果两个接口之间有相同的属性方法,可以将公共的属性方法抽离出来,通过继承来实现复用
比如 两个接口都有 x y 属性重复写两次繁琐

interface Point2D {x:number,y:number}
interface Point3D extecds Point2D {z:number}
interface Pointe2D {x:number,y:number}

//使用继承实现复用
interface Pointe3D extends Pointe2D  {
    z:number
}
let p3: Pointe3D = {
    x:1,
    y:2,
    z:3
}

使用 exteds继承关键字实现了接口Point3D继承Point2D
继承Point3D就有 Point2D所有属性方法 同时有x y z三个属性

类型断言
const aLink = document.getElementById('link') as HTMLAnchorElement
aLink.href
  • 通过使用 as 关键字实行按类型断言
  • as 后面的类型是一个更加具体类型,这样就可以访问a标签上特有属性方法
  • 类型断言另一种方式 <> 语法
const aLink = <HTMLAnchorElement>document.getElementById('link')
console.dir(aLink)
字面量类型
let str1 = 'Hello TS'
const str2 = 'Hello TS'
  • 通过 TS 类型推论机制
    1. 变量 str1 类型 string
    2. 变量 str2 类型 Hello TS
  • 解释:
    1. str1 变量 let 它的值可以是任意字符串,所以类型 string
    2. str2 常量 const 它的值不能变化只能是 Hello TS 它的类型Hello TS此处Hello TS,就是一个字面量类型。也就是某个特定的字符串也可以称作TS中的类型字符串除外,任意JS字面量比如:(object,number)都可以作为类型使用。
    • 使用模式:字面量类型配合联合类型一起使用
    • 使用场景: 表示一组明确可选值列表
    • 比如贪吃蛇游戏 上 下 左 右 任意值
function chageDirection(direction:'up'| 'down'| 'left'| 'right'){
    console.log(direction)
}
  • 参数 direction 值只能是 up down left right 任意一个
  • 优势 相比 string 类型使用字面类型更加准确,严谨
枚举

枚举的功能类似于字面量 + 联合类型组合功能也可以表示一组明确的可选值
枚举: 定义一组命名常量。他描述一个值,该值可以是遮瑕命名常量中的一个

enum Direction {Up, Down, Left, Right}
function changeDirection(direction: Direction){
	console.log(direction)
	}
  1. 使用 enum关键自定义枚举
  2. 约定枚举名称,枚举值以大写字母开头
  3. 枚举中多个值之间,分隔
  4. 定义好直接使用枚举作为类型注解
    形参 direction 类型为枚举Direction,实参的值应该是枚举Direction成员任意一个
    类似于JS中对象,通过 . 语法访问枚举成员
changeDirections(Direction.Right)

鼠标移入Direction.Up 可以看到枚举成员Up index 0
枚举成员是有值的 默认为 从0开始自增
我们把,枚举成员值为数字类型枚举: 数字枚举
也可以给枚举中成员初始化值

enum Direction {Up = 10,Down,Left,Right}

给enum第一个值 Up为10后面 Down Left Right 自增加+1

enum Direction {Up = 2,Down = 4,Left = 8,Right = 16}

字符串枚举

enum Driest {
    Top = 'top',
    Bottom = 'bottom',
    Left = 'left',
    Content = 'content'
}

字符串美剧没有自增长行为,因此,字符串枚举的每个成员必须有初始值

枚举内部发生隐式转换

let songe: string[] = ['拿骚','巴拿马']
enum Driest {
    Top = 'top',
    Bottom = 'bottom',
    Left = 'left',
    Content = 'content'
}
function changeDirection(direction:Direst){}
changeDirection(Driest.Top)

在js中做的隐式转换

var songe = ['拿骚', '巴拿马'];
var Driest;
(function (Driest) {
    Driest["Top"] = "top";
    Driest["Bottom"] = "bottom";
    Driest["Left"] = "left";
    Driest["Content"] = "content";
})(Driest || (Driest = {})); // 如果Driest对象没有值它默认为一个空对象
function changeDirection(direction) { }
changeDirection(Driest.Top);

使用字面量类型 + 联合类型组合方式

any 类型

不推荐使用 any!这会让TypeScript 变成 AnyScript (失去TS类型保护优势)
因为当值的类型为any时,可以对该值进行任意操作,并不会有代码提示

let obj:any = {x:0}
obj.bar = 100
obj()
const n :number = 100
typeof
console.log(typeof "Hello typeof")// string

TS 也提供了 typeof 操作符可以在类型上下文中引用变量属性类型
使用场景 根据已有变量的值,获取该值类型,简化类型

let p = {x:1,y:2}
function formatPoint(point:{x:number,y:number}){}
function formatPoint(point:typeof p){}
formatPoint({x:1,y:100})
  1. typeof操作符来获取变量p类型,结果与第一种(字面量类型)相同
  2. typeof出现在类型注解位置(参数名称冒号后面)所处的环境就在类型上下文
  3. typeof 只能用来查询变量或属性类型,无法查询其他类型(函数调用类型)
class类
class Person {
    age = 25
    gender = 'male'
}
const d = new Person()
d.age

在 TS 中创建类和在 JS 中都一样的 class类型关键字创建
创建实例化对象 new 关键字

实例属性初始化
实例属性有默认值不需要添加类型属性没有声明类型属性

class Pers {
    name : string
    age = 25
}
构造函数
class Person {
    name:string
    age:number
    constructor(name:string,age:number){
        this.name = name
        this.age = age
    }
}
let  p2 = new Person('梅根',39)
console.log(p2.name,p2.age)
  1. 构造函数用来实例化属性初始化,成员初始化(age:number)才可以用过 this.age 来访问实例成员
  2. 需要为构造函数指定类型注解,否则会被隐式推断 any 构造函数不需要返回值

class 类
实例方法

class Point {
    x =1
    y =2
    scale(n: number){
        this.x *= n
        this.y *= n
    }
}
const p = new Point()
p.scale(10)
console.log(p.x,p.y)

方法的类型注解(参数,返回值)与函数用法相同

继承
类继承2中方法 1 extends 继承父类 2inplements 实现接口
JS 只有 extends 而 implements 是TS提供

class Animal {
    move() {
        console.log('阿不思')
    }
}
class Dog extends Animal{
    name = '邓布利多'
    bark(){
        console.log('霍格沃兹魔法学院')
    }
}
const d = new Dog()
d.move()
d.bark()
console.log(d.name)
  1. 通过extends关键字实现继承
  2. 子类Dog继承父类 Animal,则Dog的实例对象dog旧同事具有父类Animal和子类Dog所有属性方法

实现接口
类继承2种方法 extends 继承父类 implements 接口继承

interface Singable {
    sing(): void
}
class Personer implements Singable {
    name = 'jack'
    sing() {
        console.log('赫敏')
    }
}
  1. 通过implements关键字让 class 实现接口
  2. Person 类实现接口 Singable 意味着, Person类中必须提供 Singable 接口中指定所有方法属性

class类可见修饰符

可以使用TS来控制class的方法属性对class外的代码是否可见
可见修饰符包括 public 公有 protected 受保护 private 私有

  1. public 公有公开 共有成员可以被任何地方访问默认可见性
class Animal {
  public  move() {
        console.log('阿不思')
    }
}
  • 在类属性或方法前面添加public关键字属性
  • 因为public 是more可见性可以直接省略

class类私有受保护的
protected受保护 仅对齐声明所在类子类中实现

class Animal {
  protected  move() {
        console.log('阿不思')
    }
}
class Dog extends Animal{
    name = '邓布利多'
    bark(){
        console.log('霍格沃兹魔法学院')
        this.move()
    }
}
  • 在类属性或前面添加protected关键字,来四十该属性方法是受保护的的
  • 在子类的方法内部可以通过 this 来访问父类中受保护的成员实例不可见

readonly只读修饰符
除了可见修饰符,还有一个常见修饰符是``readonly (只读修饰符)`

readonly 表示 只读用来防止构造函数之外对属性进行赋值

class Read {
    readonly age: number = 25
    constructor (age:number){
        this.age = age
    }
}
  1. 使用 readonly关键字修饰符属性只读,只能修饰符属性不能修饰方法
  2. 注意: 属性 age 后面类型注解(number此处)如果不加,age类型为25 (字面量)
  3. 接口或者{}表示对类型,也可以使用readonly
类型兼容性
  • 函数之间兼容性比较复杂需要参考: 参数个数 参数类型 返回值类型
  1. 参数个数参数多的兼容参数少的(参数少的可以赋值给多的
type F1 = (a:number) => void
type F2 = (a:number,b:number) => void
let f1:F1 
let f2:F2 
f2 = f1!

1… 参数少的可以赋值给参数据多的,所以,f1可以赋值给f2
2. 数组forEach方法的第一个参数是回调函数,类型为(value:string,index:number,array:string[])=>void
3. 在js中省略用不到的函数参数实际很常见,这样的使用方法,TS哈数类型之间的兼容性
4. TS会自动推出导出使用方法item index array类型

交叉类型

交叉类型 & 和接口继承 extends 对比

  • 相同点 都可以实现对象类型组合
  • 不同点 另种方式实现类型组合对于同名属性之间,处理 类型冲突方式不同
    不兼容
interface A {
    fn:(value:number) => string
}
interface B extends A {//报错
    fn:(vlaue:string) => string
}

交叉类型 &

interface A{
    fn:(value:number)  => string
}
interface B {
    fn:(value:string) =>string
}
type C = A & B
  • 说明已傻女代码,接口继承会报错,(类型不兼容)交叉类型没有类型错误,可以理解为:
fn:(value:string|number) => string

let c:C = {
    fn(value:number|string){
        return ''
    }
}
c.fn(1)
let a:object | number
a = [{b:'hello'}]
a = Array.isArray(a)?a:[]
泛型

泛型是可以在保证类型安全前提下,让函数等与多种类型一起工作,从而实现复用,常用于: 函数 接口 class
需要 创造一个id函数,传入什么数据就返回该数据本身(也就是,参数和返回值类型相同)

function id(value:number):number{return value}

比如id(10)调用以上函数直接返回10本身,但是应该函数只接受数值类型,无法用于其他类型
为了能让函数接受任何类型,一颗将参数修改为any,但是这样失去了TS类型保护,类型不安全

function id(value:any):any{return value}

泛型保证安全(不对事类型信息)的同时可以让函数等雨多种类型一起工作灵活可复用
实际上,在C#和java中,泛型都是用来实现可用组件功能主要工具之一
泛型
创造泛型函数

function id<Type>(value:Type):Type{return value}
  1. 语法函数名称后面添加<>尖括号,尖括号添加类型变量比如此处Type
  2. 类型变量Types是一种特殊类型变量,它处理类型而不是值
  3. 该类型变量相当于一个类型容器,能够捕获用户提供类型具体是什么类型由用户调用函数指定
  4. 因为Type是类型,因此可以将其作为函数参数返回值类型,表示该参数返回值有相同类
  5. 类型变量Type可以是任意类型
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值