TypeScript编程

TypeScript编程

一、TypeScript概念

TypeScript是JavaScript超集,完全遵循javaScript中ES5\ES6+的规范。

TypeScript强类型编程方式,可以对我们代码进行类型约束。

在你写代码的时候,需要约束类型、约束函数、约束组件之间参数传递等等

TypeScript微软发布出来,在学习TypeScript过程中实际上就是学习约束,不会在重复学习JS相关概念

强类型编程语言:定义变量的时候,必须明确规定数据类型,否则无法通过代码编译

JavaScript若类型语言:定义变量的时候,无需声明数据类型,变量数据类型由值来决定的。

js 复制代码
js:
var m = 20 //m的数据类型在写代码的时候无法确认,只有运行这段代码,内存根据20这个值决定m类型number
m =  "xiaowang" //代码运行过程m类型变成string
js 复制代码
ts:
var m:number = 20  //m类型number,内存开启8个字节
m = "xiaowang" //代码报错,m确认了数据类型后,无法接受其他值
js 复制代码
java:
int m = 20  //int短整型整数,内存4个字节存放20
long m2 = 100 //长整型整数,内存8个字节存放100

强类型语言一般都要经过过程;

比如你们写的java代码

js 复制代码
int age = 23

写完了保存代码,java环境编译这段代码,将我们java代码编译为字节码,机器能识别语言,虚拟机将字节码解释成机器语言。

弱类型语言JS无需编译:

js 复制代码
var k = 20

直接将这段代码拿到浏览器运行,一行一行的解释代码,让浏览器运行二进制代码。

问题:

  1. 你们写的JS代码,在编写过程中不是代码语法写错了,无法提示你错误信息。必须运行过程中浏览器检测出异常代码。抛出错误。

TypeScript:在JS基础上做了类型约束,编写的TS代码需要经过编译,生成JS代码,在拿去运行。将TS编译为JS代码。一旦编译过程发现错误,立马提示出来。

js 复制代码
let obj = {id:1}
obj.name = "xiaowang"

二、环境搭建

(1)安装ts的环境

js 复制代码
npm install typescript -g
tsc -v //查看版本号

(2)写一段ts代码运行

js 复制代码
let address:string = "武侯区"
console.log(address);
address = "高新区"

跟JS代码比较,在定义数据的时候,多了约束类型,数据类型。

(3)编译代码

将ts代码编译为js代码,才能在浏览器运行。

浏览器无法直接运行ts代码的。浏览器智能js、html、css

编译代码

js 复制代码
tsc index01.ts

默认在同级目录下面创建一个index01.js文件。

(4)自动编译

当检测到ts代码产生变化了,默认自己开始将ts代码编译为js代码

在指定的项目下面执行,将这个普通项目初始化ts项目

js 复制代码
tsc --init

在项目中产生一个tsconfig.json文件。这个文件里面存放项目编译的时候配置规则。

你们可以打开的配置,编译的代码默认放在同级目录的js文件夹里面。如果没有创建一个

js 复制代码
"outDir": "./js",     

终端--->运行任务-->typescript-->监视tsconfig.json

在终端开启一个监视任务,ts代码发生任何变化,理解监视代码,并编译为js代码

前期学习的时候,我们是自己搭建ts项目。

后期学习在vue框架、react框架里面使用ts

三、数据类型介绍

基本类型的数据

number、string、boolean、undefined、null

js 复制代码
let m:number = 10
let name:string = "xiaowang"
let bool:boolean = true

关于数据类型一旦约束了,那就无法在修改。数据类型在内存表示内存空间大小。

js 复制代码
//联合类型,多种类型同时存在
let m:number | undefined | null
m = null
if(m){

}

undefine和null一般不会单独使用,一般作为联合类型一起使用。给变量一个特殊的结果

引用类型

数组类型

数组、对象、

数组类型的定义:数组进行约束,指定这个数组里面存放的数据类型

js 复制代码
let array:number[] = [1,2]
let temp:string[] = ["xiaowang","1"]
let array2:boolean[] = []
array2.push(true)

默认要求数组里面只能存放同一种数据类型。

js 复制代码
//users是Array类型,存放的number类型数据
let users:Array<number> = [1,2,3]

元组类型

元组类型是一种特殊的数组,专门提出的一种数据类型。允许你数组中存放不同的数据类型,必须指定每一个位置什么类型。

js 复制代码
let students: [number, string, boolean] = [1, "xiaowang", true]
对象类型
js 复制代码
let obj:object = {}
let obj2:object = {id:1}
console.log(obj2.id);

let array3:object = [1,2,3]
let fun:object = function(){

}

object可以表示对象类型,泛指,很多类型都支持,数字、object对象、函数也都支持。

无法明确表示出具体那种对象。

js 复制代码
obj2.id //编译报错

如果针对Object类型对象,指定数据类型

js 复制代码
let classes:{id:number,name:string} = {id:1,name:"xiaofei"}

复杂类型的数据,要求约定出每一个属性的类型是什么

js 复制代码
let day:Date = new Date()

其他对象类型,用构造函数作为类型名字

其他类型

枚举类型

js 复制代码
let order = {
    id: 1,
    name: "普通订单",
    status: 0
}

//枚举,将各种状态,用枚举的方式列举出来。
enum orderState {
    payError = 0,
    paySuccess = 1,
    payTimeout = 2
}

//不符合编码规范的
// 0 1 魔法数字(魔鬼数字),不能出现魔法数字
if (order.status == orderState.payError) {

} else if (order.status == orderState.paySuccess) {

} else {

}

枚举的状态一定有限的,可控的。

any类型

js 复制代码
//当代码中无法明确指定数据类型的时候,你可以any占位。
let mode:any = true
const app:any = document.getElementById("app")

作业1:

js 复制代码
题目一:使用原型或class的方式来实现js的链式调用,对数字进行加减乘除
案列:new myCalculator(100).add(1).reduce(100)   ===》输出结果为1

作业2:

js 复制代码
说明:定义一个函数,接受三个参数getMaxNumber(array,k,m){},找出第k大和第m大的数字之和。重复的数据也需要计算

比如:[1,3,4,5,4,6]   k=1的时候获取到值为6(出现一次),m=3的时候获取到的只为4(出现2次),总和就是 sum = 6+4+4

作业3:

js 复制代码
对数组进行排序,数组的数据格式不定。

>比如:[1,2,5,4,8] ===>返回 [1,2,4,5,8]
>
>比如:[1,3,[4,7],[6,5,9]] ===>返回 [1,3,4,5,6,7,9]

四、函数定义

在TS中函数研究两个内容

  1. 函数参数
  2. 函数的返回值

参数的传递方式

js 复制代码
/**
 * 参数:接受基本类型
 * @param val 
 * @param val2 
 */
function show(val:number,val2:string){
    
}
show(1,"xiaowang")

/**
 * 参数:接受引用类型
 * @param val 
 * @param obj 
 */
function play(val:number,obj:{id:number}){

}
play(1,{id:1})

/**
 * 接受函数类型
 * @param fun 
 */
function play2(fun:()=>void){
    fun()
}
play2(()=>{})

/**
 * 不定参数的场景
 * @param args 
 */
function play3(...args:number[]){
    console.log(args[0]);
    
}
play3(1,2,3,4,5)

函数返回值

js 复制代码
/**
 * 函数的参数基本类型
 * 函数返回值,
 * @param val1 
 * @param val2 
 * @returns 
 */
function play4(val1: number, val2: number):number {
    return val1 + val2
}

const res = play4(1,2)

"123".substring(1,2)
const res2 = "1379002346".replace(/[13]/,"**")

箭头函数

js 复制代码
const message = (params1:number):number=>{
    return params1 * 2
}
message(2)

在设计工具类,在设计业务的时候,在函数调用过程中检测出你参数问题。

不至于项目要浏览器运行起来才知道自己参数传递错误

案列:

定义一个函数,接受一个数组,返回数组中最大值

js 复制代码
function getMaxValue(args:number[]):number{
    let max = args[0]
    args.forEach(item=>{
        max = max < item ? item : max
    })
    return max
}
let temp2:number[] = [1,5,7,9]

const max = getMaxValue(temp2)
console.log(max);

五、接口的概念

接口是一种约束、是一种规范。

比如后端接口:表达的后端返回的数据有什么约束、条件、格式等等。

在TS中接口,用于设计数据类型约束。复杂的数据类型,你可以用接口来约束。

属性类型接口

接口的定义

js 复制代码
/**
 * 设计一个接口,
 * 我自己定义一种数据类型
 */
interface IStu {
    id: number,
    name: string,
    gender: string,
    classes: string
}

let students: IStu[] = [
    { id: 1, name: "杜欣", gender: "女", classes: "web35" },
    { id: 2, name: "袁令", gender: "男", classes: "web35" },
    { id: 3, name: "童瑶", gender: "女", classes: "web34" }
]

多个interface嵌套

js 复制代码
/**
 * 定义一个学生数组
 * 学生:编号、名字、性别、班级
 */

/**
 * 设计一个接口,
 * 我自己定义一种数据类型
 */
interface IStu {
    id: number,
    name: string,
    gender: string,
    classes: IClasses,
    phone?:string
}
interface IClasses {
    cid: number,
    name: string
}

let students: IStu[] = [
    {
        id: 1, name: "杜欣", gender: "女", phone: "344", classes: {
            cid: 1, name: "web35"
        }
    },
    {
        id: 2, name: "袁令", gender: "男", classes: {
            cid: 2, name: "web34"
        }
    },
    {
        id: 3, name: "童瑶", gender: "女", classes: {
            cid: 3, name: "web33"
        }
    }
]

function getValue(students: IStu[], search: string) {
    let stu = students.find(item => item.name == search)
    return stu
}

const result = getValue(students, "童瑶")

//?.是一种新的运算符,ES2020这个版本推出来。 可选链运算符
// result是undefined或者null的时候 不会.id
console.log(result?.id);


export { }

练习:

  1. 定义一个员工数组(id、name、age、address)
  2. 定义一个函数,传递一个数组,找到年龄最大的员工
  3. 定义一个函数,传递一个数组和名字,根据名字模糊搜索
  4. 定义一个函数,按照年龄升序排列,返回这个数组。
js 复制代码
/**
 * 练习:
1. 定义一个员工数组(id、name、age、address)
2. 定义一个函数,传递一个数组,找到年龄最大的员工
3. 定义一个函数,传递一个数组和名字,根据名字模糊搜索
4. 定义一个函数,按照年龄升序排列,返回这个数组。
 */
interface IEmp {
    id: number;
    name: string;
    age: number;
    address: string;
}
let emps: IEmp[] = [
    { id: 1, name: "小王", age: 23, address: "成都" },
    { id: 2, name: "小张", age: 24, address: "武汉" },
    { id: 3, name: "小吴", age: 22, address: "北京" }
]

function getMaxAagEmp(emps: IEmp[]) {
    const temp = emps.map(item => {
        return item.age
    })
    //Math.max获取一堆数据最大值 Math.max(...temp)
    const maxAge = Math.max.apply(emps, temp)
    const emp = emps.find(item => item.age == maxAge)
    return emp
}

function searchByName(emps: IEmp[], key: string): IEmp[] {
    const temp = emps.filter(item => {
        if (item.name.indexOf(key) != -1) {
            return true
        }
    })
    return temp
}


function orderByAes(emps: IEmp[]) {
    emps.sort((a, b) => {
        return a.age - b.age
    })
    return emps
}

类型断言

我比程序更清楚我的数据类型是什么。

两种语法

js 复制代码
(obj as any).age
(obj as IStu).age
(<IStu>obj).age

案列

js 复制代码
interface IUser {
    id: number,
    name: string
}
interface IStu {
    id: number,
    name: string,
    age: number
}

//联合类型 union代表一种数据类型。
type union = IUser | IStu

/**
 * 当编辑器推断出来的类型 不满足要求,报错的时候。强行给编辑器提示。
 * 这个过程类型断言
 * @param obj 
 */
function change(obj: union) {
    console.log(obj.id);
    console.log((obj as any).age);
    console.log((obj as IStu).age);
    console.log((<IStu>obj).age);
}

change({ id: 1, name: "xiaowang" })
change({ id: 1, name: "xiaowang", age: 23 })


export { }

练习:

定义一个函数,传递日期对象,传递一个字符串格式,根据字符串格式返回对应的数据格式

js 复制代码
format(new Date(),"yyyy-MM-dd") --->2023-10-31
format(new Date(),"yyyy/MM/dd") --->2023/10/31
format(new Date(),"yyyy/MM/dd hh:mm:ss") --->2023/10/31 15:14:20

代码

js 复制代码
/**
format(new Date(),"yyyy-MM-dd") --->2023-10-31
format(new Date(),"yyyy/MM/dd") --->2023/10/31
format(new Date(),"yyyy/MM/dd hh:mm:ss") --->2023/10/31 15:14:20
字符串替换。"yyyy-MM-dd".replace("yyyy",date.getFullYear())
正则来匹配
 */
function format(date: Date, type: string): string {
    const obj: any = {
        "y+": date.getFullYear(),
        "M+": date.getMonth() + 1,
        "d+": date.getDate(),
        "h+": date.getHours(),
        "m+": date.getMinutes(),
        "s+": date.getSeconds()
    }
    //根据obj这个对象中的内容 和type的内容进行匹配。
    //type = "yyyy-mm-dd"
    for (const key in obj) {
        // /(y+)/
        if (new RegExp("(" + key + ")").test(type)) {
            type = type.replace(RegExp.$1, obj[key])
        }
    }
    return type
}

const resultDate = format(new Date(),"yyyy-MM-dd")
const resultDate2 = format(new Date(),"yyyy-MM-dd hh:mm")
console.log(resultDate2);

可索引接口

这个模块用的比较少。遇到了理解他概念

概念:有时候你并不知道类型的所有属性名字,你只能确认属性值为number或者string的时候,你可以用可索引接口来约束我们代码

js 复制代码
interface IUser {
    [index:number]:string
}

可索引接口,可以表示两种数据类型,第一种数组,第二种对象。

js 复制代码
array = [1,2,3]
array[0]
obj = {id:1,name:"xiaowang"}
obj["name"]

数组的可索引定义语法

js 复制代码
/**
 * [index:number]:代表这块内容是动态,不约束名字,值得类型被约束
 * index:索引名字。默认都是这个名字,索引默认用number array[1]
 */
interface IArray {
    [index:number]:number
}

const temparray:IArray = [1,3,4]
temparray[0]

对象得可索引接口语法

js 复制代码
/**
 * 当我不知道对象里面到存放什么属性,只能用可索引接口
 */
interface IObj {
    [index:string]:string | number
}
const obj23:IObj = {}
obj23.id = 1
obj23.name = "xiaowang"

索引值得类型,索引值类型为string,代表允许我们通过string类型来作为索引获取数据

js 复制代码
interface IObj {
    [index:string]:string | number
}
const obj23:IObj = {id:1,name:"xiaoawng"}
obj23["id"]

练习题一:

  1. 确定有id和name,请取出来中值构造成对象
  2. 不确定到底传递过来有多少个键值对,都要封装为对象返回
js 复制代码
http://127.0.0.1:8888?id=1&name=xiaowang
useLocation() ---> {search:"?id=1&name=xiaowang"}

{id:"1",name:"xiaowang"}

练习题二:

定义一个函数,接受电话号码,将中间得4位用*隐藏起来 返回电话号码

比如:13890012345--->138****2345

练习题三:

找出字符串中只出现一次的字母,返回第一个就可以。

js 复制代码
console.log(firstAppear("abacdefeg")); 返回`b`

六、泛型

设计一个函数,要求进行数据排序

在TS程序设计过程中,约束越来越严格,导致参数得类型固定了。很多代码无法进行扩展

js 复制代码
/**
 * 
 * @param array 
 * @param orderBy 
 * @returns 
 */
function sortData(array: number[], orderBy: number) {
    if (orderBy == 1) {
        array.sort()
    } else {
        array.sort((a, b) => {
            return b - a
        })
    }
    return array
}
sortData([1, 2, 3, 4, 5], 1)
sortData(["a", "b", "d", "c"], 2)

定义函数参数类型number,下次string类型得数组就无法使用这个函数。

提出了一个泛型得概念

泛型:泛指某个类型,数据类型也是动态可以变化得。

js 复制代码
/**
 * 
 * @param array 
 * @param orderBy 
 * @returns 
 */
function sortData<T>(array: T[], orderBy: number) {
    if (orderBy == 1) {
        array.sort()
    } else {
        array.sort((a, b) => {
            return b - a
        })
    }
    return array
}
sortData<number>([1, 2, 3, 4, 5], 1)
sortData<string>(["a", "b", "d", "c"], 2)

多个泛型

js 复制代码
function computed<T,K>(params:T,params2:K){

}
computed(1,2)
computed<string,number>("2",3)

泛型的使用,为了让数组能够存放指定数据类型。Array内部没有规定死类型,用户使用通过泛型来决定数组里面存放的值类型

js 复制代码
let array:Array<number> = [1,2,3]
let array:Array<string> = [1,2,3]

案列:

js 复制代码
/**
 * 定义一个函数,获取一个数组,求最大值
 * 不确定数组是number、string
 */
function getMaxValue<T>(array: T[]): T {
    let max = array[0]
    array.forEach(item => {
        max = max < item ? item : max
    })
    return max
}

getMaxValue([1, 2, 3, 4])
getMaxValue(["a", "b", "c"])


export { }
相关推荐
Jinxiansen021132 分钟前
Vue 3 实战:【加强版】公司通知推送(WebSocket + token 校验 + 心跳机制)
前端·javascript·vue.js·websocket·typescript
龚思凯2 小时前
TypeScript 中 typeof 的全面解析:从基础用法到高级技巧
前端·typescript
jstart千语2 小时前
【vue3学习】vue3入门
前端·javascript·vue.js·typescript·vue
struggle20258 小时前
RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上
数据库·typescript·neo4j
狂炫一碗大米饭14 小时前
如何在 TypeScript 中使用类型保护
typescript
码农之王19 小时前
(一)TypeScript概述和环境搭建
前端·后端·typescript
蚂小蚁1 天前
从DeepSeek翻车案例看TypeScript类型体操的深层挑战
typescript·deepseek·trae
在人间耕耘2 天前
鸿蒙应用开发:WebSocket 使用示例
typescript
在人间耕耘2 天前
uni-app/uniappx 中调用鸿蒙原生扫码能力的实践
typescript
海的诗篇_2 天前
前端开发面试题总结-JavaScript篇(二)
开发语言·前端·javascript·typescript