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 { }
相关推荐
shenyaofeng3 天前
React 封装高阶组件 做路由权限控制
前端·javascript·react.js·职场和发展·typescript
草明3 天前
TypeScript 学习
javascript·学习·typescript
Dragon Wu5 天前
electron typescript运行并设置eslint检测
前端·javascript·typescript·electron·前端框架
草明5 天前
TypeScript 学习 -类型 - 9
javascript·学习·typescript
草明5 天前
TypeScript 学习 -类型 - 8
javascript·学习·typescript
觉醒法师7 天前
JS通过ASCII码值实现随机字符串的生成(可指定长度以及解决首位不出现数值)
开发语言·前端·javascript·typescript
徐_三岁8 天前
TypeScript 中的 object 和Object的区别
前端·javascript·typescript
ThomasChan1239 天前
Typesrcipt泛型约束详细解读
前端·javascript·vue.js·react.js·typescript·vue·jquery
我能与泰森过两招9 天前
鸿蒙next 自定义日历组件
typescript·harmonyos·鸿蒙
yg_小小程序员9 天前
鸿蒙开发(32)arkTS、通过关系型数据库实现数据持久化封装
数据库·华为·typescript·harmonyos