TypeScript基础

发布时间 2023-07-05 00:25:52作者: wdszh

TypeScript基础

类型

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

常量

// 定义一个常量,常量定义之后就不能修改了
const anExampleVariable = "Hello World"

// 给常量重新赋值会报错
// anExampleVariable = "abc"

变量

类型递推

  • TS拥有自动的类型判断机制
  • 当对变量的声明和赋值是同时进行的,TS编译器会自动判断变量的类型
  • 所以如果你的变量的声明和赋值时同时进行的,可以省略掉类型声明
// 定义变量(类型递推,推荐这么写简洁)
let var1= "Hello World"

// 给变量重新赋值
var1= "aaa"

// 定义变量(指定类型,不建议这么写除非必须)
let var2: string = "Hello World"
var2= "aaa"


// 定义变量(指定并集类型)
let var3:string|number = 123
var3 = "abc"


// 定义变量,使用any来指定任何类型
let var4:any = "abc"
// 此时可以给变量任意类型的值
var4 = 123
var4 = true

String Literal Types(字面量)

规定变量只能是这枚举的值,类似枚举

//  规定变量answer只能是这枚举的值,并且answer赋值为yes
let answer: "yes"|"no"|"maybe" = "yes"

// 规定变量num只能是这枚举的值,并且num未赋初始值
let num: 1 | 2 | 3 | 4 | 5

逻辑控制

  • if/else
  • switch
  • for
  • while
  • try/catch

枚举

示例:

// 定义一个枚举
enum HTTPStatus{
    OK = 200,
    NOT_FOUND = 404,
    INTERNAL_SERVER_ERROR = 500,
}

// 方法参数为枚举
function processHTTPStatus(status:HTTPStatus){
    // 枚举值为数值
    console.log(status)
    // 获取枚举的字符串值
    console.log(HTTPStatus[status])
}

// 枚举赋值
let var5 = HTTPStatus.OK
var5 = 500

processHTTPStatus(var5)

数组

// 数组里面存储多种类型的元素
let arr1:(string | number | boolean)[] = [1,2,3, "a",true]

// 数组里面存储一种元素
let arr2:number[] = [1,2,3]

// 使用类型递推(建议这么写,简洁)
let arr3 = [1,2,3, "a",true]

// 数组的属性length来获取数组的长度
console.log(arr3.length)

// 给某个位置的元素赋值
arr1[3] = 100

// 获取指定位置的值
console.log("arr1[3]=",arr1[3])

// 向数组尾部(右边)添加一个元素
arr1.push(9)

// 取出数组尾部(右边)元素
console.log("arr1.pop=", arr1.pop())

// 向数组头部(左边)添加一个元素
arr1.unshift(100)

// 取出数组头部(左边)元素
console.log("arr1.shift=", arr1.shift())

slice

let arr0 = [1,2,3, "a",true]
// 取数组的[1-2)位置的元素,左闭右开(包含左边,不包含右边)
let arr1 = arr0.slice(1,2)
// 当右边的值大于数组最大下标值时取到最后一个
console.log(arr1, arr0.slice(3,5))


arr0.splice(3,1)

console.log(arr0)

splice

let arr0 = [1,2,3, "a",true]
// 删除元素,从2号位置开始(包括2),共删除一个元素,同时返回删除的元素(一个数组)
let deleted = arr0.splice(2,1)

console.log(arr0, "deleted=", deleted)

indexOf

let arr0 = [1, 2, "a", "a", true, 5]

// 找元素在数组中的位置,当存在多个时只会返回第一次出现的位置
const i = arr0.indexOf("a")

console.log(i)


// indexOf第二个参数表示从第几个位置查找(包含这个位置)
console.log(arr0.indexOf("a", 3))

其它用法

let arr0 = [1,2]

// 解构数组中的元素,此时a=1,b=2,c=undefined
const [a,b,c] = arr0

console.log(a,b,c)

// split 将一个字符串使用指定字符分割成一个数组
let var1 = "1,2,3".split(",")
console.log(var1)

// join 将一个数组中的元素使用指定的字符连接成一个新的字符串
let var2 = arr0.join(" ")
console.log(var2)

// map reduce
const arr = [1,2,3]

const sum = arr
.map(v=>v*v)
.reduce((s,v)=>s+v)


console.log(sum)

对象

// 定义一个对象
const emp1 = {
    name:"ZhangSan",
    // 属性的值只能是这几个类型
    gender:"M" as "M" | "W" | "other",
    salary: 12000,
    // 属性的类型只能是number或者undefined
    bonus: undefined as number | undefined,
    performance: 1.5,
}

if(!emp1.bonus){
    emp1.bonus = emp1.salary * emp1.performance
}

console.log(emp1)

// 对象序列化成字符串
const jStr = JSON.stringify(emp1)

// 字符串反序列化成对象
const emp2 = JSON.parse(jStr)

console.log(emp2)

函数

// 函数定义
function add(a:number, b:number): number{
    return a+b
}

// 函数定义,返回值类型可以不写(推荐)
function add(a:number, b:number){
    return a+b
}

// 可选参数 c
// 默认值 d
// 可变参数 e
function add(a:number, b:number, c?:number, d:number=0, ...e:number[]):number{
    let value = c ? a+b+c+d : a+b+d
    for(let i =0; i < e.length;i++){
        value += e[i]
    }
    return value
}

// 可变参数函数
function add2(...items:number[]):number{
    let value = 0
    for(let i =0; i < items.length;i++){
        value += items[i]
    }
    return value
}

const data = [1,3,5,7,9]

// 函数入参为可变参数时解构写法
console.log(add2(...data))

函数重载(不太建议使用)

// 函数声明
function add(a:number, b:number):number
function add(a:number, b:number,...e:number[]):number

// 函数实现
function add(a:number, b:number, c?:number, d:number=0, ...e:number[]):number{
    let value = c ? a+b+c+d : a+b+d
    for(let i =0; i<e.length;i++){
        value += e[i]
    }
    return value
}
// 使用的时候就可以使用上面声明的这2个函数

对象类型作为函数参数(当一个函数参数过多时建议这样定义)

// 函数参数为一个对象
function sendRequest(params:{
    url: string,
    // 指定method的值
    method: 'GET' | 'POST' | 'PUT',
    header: object,
    // 可选参数
    data?: string,
    auth: boolean,
    retry: boolean,
    retryTimeout?: number,
}){
// do something
}

// 调用这个方法传参
sendRequest({
    url:'http://www.baidu.com',
    method:'GET',
    header:{},
    auth:false,
    retry:false
})

给对象定义方法(函数)

const emp1 = {
    name:"ZhangSan",
    // 属性的值只能是这几个类型
    gender:"M" as "M" | "W" | "other",
    salary: 12000,
    // 属性的类型只能是number或者undefined
    bonus: undefined as number | undefined,
    performance: 1.5,
    updateBonus(){
        if(!this.bonus){
            this.bonus = this.salary * this.performance
        }
    },
}

// 调用对象的方法
emp1.updateBonus()

console.log(emp1)

函数式编程

TypeScript中的函数式编程包括如下部分

  • 函数是一等公民

  • 高阶函数

  • 闭包

  • 部分应用函数(lambda表达式)

函数是一等公民

方法参数,返回值,对象属性,变量等都可以是函数

function compareTo(a:number, b:number){
    return a-b
}

// 返回值是函数
function getCompareTo():(a:number,b:number) => number{
    return compareTo
}

// 返回值是函数,方法返回值声明可以沈略
function getCompareTo2(){
    return compareTo
}

// 方法参数是一个函数
function arrSort(arr:number[], compareFun:(v1:number, v2:number)=> number){
    arr.sort(compareFun)
}


const arr = [2,3,1,9,4,0,20,1]
// 变量可以是一个函数
const compare = getCompareTo2()

arrSort(arr, compare)

console.log(arr)

// lambda表达式(箭头函数),部分应用函数
arr.sort((v1,v2)=> v1-v2)

console.log(arr)

高阶函数

高阶函数是指至少下面条件之一的函数

  • 函数作为参数传递
  • 函数作为返回值输出

闭包

一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。闭包的特点:

  1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态
  2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区
function getFun(){ 
    // 变量的生命周期延长
    let a = 0
    return function(){ 
        a++
        return a
    } 
}

// getFun返回的是一个闭包
const func = getFun()

console.log(func())
console.log(func())
console.log(func())

闭包经常与高阶函数一起使用