当前位置: 首页 > news >正文

【TypeScript】进阶之路语法细节,类型和函数

进阶之路

      • 类型别名(type)的使用
      • 接口(interface)的声明的使用
        • 二者区别:
      • 联合类型和交叉类型
        • 联合类型
        • 交叉类型
      • 类型断言
          • 获取DOM元素
      • 非空类型断言
      • 字面量类型的使用
      • 类型缩小(类型收窄)
      • TypeScript 函数类型
          • 函数类型表达式
          • 内部规则检测
          • 函数的调用签名
          • 如何选择他们?
        • 参数的可选类型
        • 参数的默认值
        • 剩余参数
      • 函数重载
      • 函数重载-联合类型(优先使用)

类型别名(type)的使用

  • 为解决给联合类型的类型定义过长的问题
  • 使用类型别名
// 使用关键字type定义类型别名对象,可以复用
type myname = number | string
function hander1(name: myname) {console.log(name)if (typeof name === 'string') {console.log(name.length)}
}
//不使用类型别名
function hander2(x: number,y:number,z?:number) {
}
//使用类型别名
type myx={x: number,y:number,z?:number}
function hander3(mytype:myx) {
}

接口(interface)的声明的使用

  • 关键字使用interface声明
  • 相比较类型别名,少了=
//接口interface,没有=号
interface myX2 {x: number y: number z?: number
}
//使用接口声明
function hander4(mytype: myX2) {
}

二者区别:

  • 类型别名和接口声明非常相似,在定义对象的时候,可以任意选择使用
  • 主要区别:
  • type类型使用范围更广
  • type定义的是别名,不允许两个相同名称的别名使用
type myname = number | string
  • 1,接口类型只能用来声明对象
  • 2,接口类型声明对象的时候可以多次声明
  • 3,接口类型支持继承
  • 4,接口类型支持被类实现
//接口interface,没有=号,可以多次声明
interface myX2 {x: number y: number 
}
//接口interface,没有=号
interface myX2 {z?: number
}
//使用接口声明
function hander4(mytype: myX2) {
}//接口interface,支持继承
interface myX2 {x: number y: number 
}
interface myX3 extends myX2 {z?: number
}
function hander5(mytype: myX3) {console.log(mytype.x,mytype.y,mytype.z)
}
hander5({x:1,y:2,z:3})

联合类型和交叉类型

联合类型

  • ts允许我们使用多种运算符,从现有类型中构建新类型
  • 联合类型由两个或多个类型组成的类型
  • 表示可以是这些类型中的任何一个值
  • 联合类型中的每一个类型被称为联合成员
// 联合类型
function hander(name: number | string) {console.log(name)
}
hander(1)
hander("123")//联合类型
let nainfo: number | string = "abc"
nainfo = 1
nainfo = "123"//但联合类型要使用的时候,要注意类型缩小,类似
// 联合类型
function hander1(name: number | string) {console.log(name)if (typeof name === 'string') {console.log(name.length)}
}
hander1(1)
hander1("123")
  • 注意:
  • 在拿联合类型的值之后,因为它可能是任何一种类型,如何使用呢?
  • 类似拿到的是number,就不能使用string的一些方法
  • 解决:
  • 需要使用缩小集合,也就是类型缩小,根据缩小的代码,推断出更加具体的类型

交叉类型

  • 交叉类型表示需要满足多个类型的条件
  • 交叉类型使用&符号
//交叉类型,两种或者多种类型同时满足
type myY = number & string//想同时满足数值和字符串类型,不可能,估没有意义
type myY2 = number & stringinterface myX2 {x: numbery: number
}
interface myX3 {z?: numberp: () => void
}
//表示即满足myX2也得满足myX3,否则里面会有报错提示
const info: myX2 & myX3 = {x: 1,y:2,p:()=>{console.log("方法")}
}

类型断言

  • 有时候ts无法获取具体额度类型信息,这个时候需要使用类型断言
  • ts只允许类型断言转换为更具体的或者不太具体的类型版本,此规则可防止不可能的强制转换
获取DOM元素

在这里插入图片描述

// <img class="img">。使用类型缩小使用,只知道会返回html类型,但不知道具体类型
const imgE1 = document.querySelector("img")
// imgE1.src = "",会报错
if (imgE1 != null) {imgE1.src = ""
}
// <img class="img">。此时imgE2为element,不能直接使用,使用类型断言
//当你确信他存在且为html时,直接使用类型断言为更具体的样子,
const imgE2 = document.querySelector(".img") as HTMLImageElement
imgE2.src = ""

在这里插入图片描述

  • 类似,这样。类型断言成不太具体的样子
const num = 12
const num2 =num as any
  • 也可以继续,将不太具体的类型类型断言成更具体的样子
  • 但不支持这样来回断言,有安全隐患
const num = 12
const num2 =num as any
const num3 =num2 as string

非空类型断言

  • 当传入的值有可能为undefined时,这个时候方法不能执行
  • 采用符号!,必须确保某个标识符是有值的,可以跳过ts在编译阶段对它的检测
interface hander{name:string,age:number,size?:number
}
const info: hander={name:"乞力马扎罗",age:18
}
//访问可以用可选的
console.log(info?.size)//赋值的时候,可选链不行
// info?.size=23// 解决方法:
// 1,类型缩小
if(info.size){info.size=23
}
// 2.非空类型断言,有点危险,确保非空值的父值一定有值,才能使用
info!.size=23
console.log(info.size)//23

字面量类型的使用

  • 将赋予的值当做类型,使用的时候只能使用字面量
  • 默认情况下没有多大意义,但是可以将多个类型联合在一起,你只能是我们中一个

在这里插入图片描述

type numtype = "left" | "top" | "up"
const num3: numtype = "left"// 使用背景
// 一般请求方式,get或者post
// 采用这种方式,可以让用户必须传get或者post,否则报错
type requestype = "get" | "post"
function reqest(url: string, method: requestype) {}
reqest('http//xxx.com', 'get')
  • 使用背景
// 使用背景
// 一般请求方式,get或者post
// 采用这种方式,可以让用户必须传get或者post,否则报错
type requestype = "get" | "post"
function reqest(url: string, method: requestype) {}
const  hander={url:'xxx',method:'post'
}
// reqest('http//xxx.com',hander.method)
//报错,报错原因,不认识你这个hander.method获取的是string类型,不是get或者post
  • 解决方法1
// 解决方法1:类型断言
reqest('http//xxx.com',hander.method as "post")
  • 解决方法2
// 解决方法2,直接让hander对象是个字面量类型
const  hander1 :{ url:string,method:'post'}={url:'xxx',method:'post'
} as const
reqest('http//xxx.com',hander1.method)
// 或者,字面量推理
const  hander2={url:'xxx',method:'post'
} as const
reqest('http//xxx.com',hander2.method)

类型缩小(类型收窄)

  • 可以通过类似下面的判断语句,来改变ts的执行路径
if(info.size){info.size=23
}
  • 类似这样的语句也称之为类型保护
  • 在给定的执行路径中,可以缩小比声明时更小的类型,这个过程称之为缩小
  • 常见的类型保护
  • typeof,检查返回的类型
type requestype = "get" | "post"
function reqest(url: string, method: requestype) {if(typeof url ==='string'){console.log(url)}
}
  • 平等缩小(=== 和!== 和==等等),字面量的判断
type requestype = "get" | "post"
function reqest(url: string, method: requestype) {if(method==="get"){console.log(method)}
}
  • instanceof,表示是不是这个的实例
//传入一个实例
function reqest(data:string|Date) {if(data instanceof Date){console.log(data.getTime())}
}
  • in ,用于确定对象是否具有带名称的属性,in 运算符
  • 等等…

TypeScript 函数类型

函数类型表达式
  • 可以编写函数类型的表达式,来表示函数类型
  • ts中,函数类型中的形参名是不能省略的
// 函数类型表达式
// 格式:(参数列表)=>返回值
const fun: (num2: number) => number = (arg: number): number => {return 123
}
// 为了可阅读性,类型形参里的名不能省略
type funtype = (num2: number) => number//这个就代表一个函数类型
const fun2: funtype = (arg: number) => {return 123
}// 例子,传入计算方式,计算两位数字,js写法
function cals(func) {const num1 = 12const num2 = 13const res = func(num1, num2)
}
function func1(num1, num2) {return num1 + num2
}
cals(func1)//ts写法
type calstype = (num1: number, num2: number) => number
function cals1(func: calstype) {const num1 = 12const num2 = 13const res = func(num1, num2)
}
function func2(num1: number, num2: number) {return num1 * num2
}
cals1(func2)
内部规则检测
// ts对于很多的类型的检测报不报错,取决于它的内部规则
interface gule {name: stringage: number
}
//直接写报错,原因,第一次定义的时候,会检测规则报错
//  const info:gule={
//    name:"山头",
//    age:12,
//    size:'大'
//  }//但取决于内部规则,赋值完,再使用,这样就没检测,单指size的增加,其他已定义的还是会检测
const p = {name: "山头",age: 12,size: '大'
}
const info: gule = p
函数的调用签名
  • 在js中,函数除了可以被调用,自己也可以有属性值的
  • 类型表达式并不能支持声明属性
  • 当你想要一个带有属性的函数,就可以在一个对象类型中写一个调用签名
//函数表达式,这里是箭头
//不能声明其他属性
type obj2 = (num1: number) => number//调用签名
interface obj {name: stringage: number//函数可以调用:函数调用签名,这里是冒号(num1: number): number
}const func: obj = (num1: number): number => {return 123
}
func(123)
如何选择他们?
  • 如果只是描述函数类型本身(函数类型可以被调用),使用函数表达式
  • 如果再描述函数作为对象可以被调用,同时也有其他属性时,使用函数调用签名

参数的可选类型

  • 可选参数必须放在必传参数的后面
// 可选参数类型是什么
// 当不传的时候,y就是undefined类型,也就是number|undefined联合类型
function fun(x:number,y?:number){console.log(x,y)if(y!=undefined){console.log(y)}
}
fun(1)

参数的默认值

// 函数的参数有默认值
// 有默认值的情况下,参数的类型注解可以省略
// 此时,有默认值的参数,哪怕是number,也可以接收一个undefined类型
function fun(x:number,y=100){console.log(x,y)if(y!=undefined){console.log(y)}
}
fun(1)

剩余参数

  • 剩余参数语法允许我们将一个不定数量的参数表示为一个数组。
  • 利用剩余参数我们可以定义一个形参不固定的计算和的函数。
function sum (first, ...args) {console.log(first); // 10console.log(args); // [20, 30] 
}
sum(10, 20, 30)// 或者
// 剩余参数,通过这种方式扩展了类型注解
function fun(...arrs: (string| number)[]) {}
fun(1,2,3,'4')

函数重载

  • ts中,可以去编写不同的重载函数,来表示函数可以以不同的方式进行调用
  • 一般是编写两个或者以上的重载签名。再去编写一个通用的函数以及实现
// 需求。将两个数字或者字符串相加
// 联合类型,这个案例用不了// 普通实现
// function add(n1, n2) {
//    return n1 + n2
// }
// add(1,2)通用函数不可调用//函数重载
//1,先编写重载函数
function add2(n1:number, n2:number):number
function add2(n1:string, n2:string):string//2,再编写通用的函数
function add2(n1:any, n2:any) {return n1 + n2
}
console.log(add2(1,2))//3
console.log(add2("1","2"))//12// add2("1",2)//函数 不能被调用,没有对应的重载函数

函数重载-联合类型(优先使用)

  • 能用就用联合类型
//函数重载-联合类型
//定义一个函数,可以传入字符串或者数组,获取他们的数组
//1,编写重载函数-联合类型
function add2(arg:string|any[]) {return arg.length
}
console.log(add2("123"))//3

相关文章:

【TypeScript】进阶之路语法细节,类型和函数

进阶之路 类型别名(type)的使用接口(interface)的声明的使用二者区别&#xff1a; 联合类型和交叉类型联合类型交叉类型 类型断言获取DOM元素 非空类型断言字面量类型的使用类型缩小&#xff08;类型收窄&#xff09;TypeScript 函数类型函数类型表达式内部规则检测函数的调用签…...

每日一题 611有效三角形的个数(相向双指针)

题目 给定一个包含非负整数的数组 nums &#xff0c;返回其中可以组成三角形三条边的三元组个数。 示例 1: 输入: nums [2,2,3,4] 输出: 3 解释:有效的组合是: 2,3,4 (使用第一个 2) 2,3,4 (使用第二个 2) 2,2,3示例 2: 输入: nums [4,2,3,4] 输出: 4 题解 class Solu…...

Flink源码之JobMaster启动流程

Flink中Graph转换流程如下&#xff1a; Flink Job提交时各种类型Graph转换流程中&#xff0c;JobGraph是Client端形成StreamGraph后经过Operator Chain优化后形成的&#xff0c;然后提交给JobManager的Restserver&#xff0c;最终转发给JobManager的Dispatcher处理。 Completa…...

C#,数值计算——抛物线插值与Brent方法(Parabolic Interpolation and Brent‘s Method)的计算方法与源程序

using System; namespace Legalsoft.Truffer { /// <summary> /// 抛物线插值与Brent方法 /// Parabolic Interpolation and Brents Method /// </summary> public class Brent : Bracketmethod { public double xmin { get; set…...

基于Selenium技术方案的爬取界面内容实践

1. 定位页面&#xff08;多窗口切换&#xff09; WebDriver提供了处理多个窗口的能力&#xff0c;这是通过使用“WebDriver.switchTo.window()”方法来切换到已知名称的窗口来实现的。如果名称未知&#xff0c;您可以使用“WebDriver.getWindowHandles()”获取已知窗口列表。您…...

线程记录(1)

创建线程&#xff1a; 一、1.继承Thread&#xff0c;重写run()&#xff0c;将操作写入其中 2.创建子类对象&#xff0c;start() 二、1.实现runnable接口&#xff0c;实现run() 2.创建子类对象&#xff0c;将子类对象作为参数传递到thread的构造器中&#xff0c;创建出Thread类…...

requests

操作步骤 安装 requests 发送GET请求 发送POST请求 说明&#xff1a; data: 参数接收form表单数据&#xff0c;后台会⾃动附加form表单请求信息头&#xff08;data数据格式为字典&#xff09; json:参数接收json数据&#xff0c;后台会⾃动附加json表单请求信息头&…...

Python 监控 Windows 服务

Python 监控 Windows 服务 Python 在 Windows 系统上可以使用 wmi 模块来实现对 Windows 服务的监控。本文将介绍如何使用 Python 监控 Windows 服务&#xff0c;并实现服务状态的查询和服务启停功能。 安装依赖 在使用 wmi 模块之前&#xff0c;需要先安装 wmi包。可以使用…...

ELK中grok插件、mutate插件、multiline插件、date插件的相关配置

目录 一、grok 正则捕获插件 自定义表达式调用 二、mutate 数据修改插件 示例&#xff1a; ●将字段old_field重命名为new_field ●添加字段 ●将字段删除 ●将filedName1字段数据类型转换成string类型&#xff0c;filedName2字段数据类型转换成float类型 ●将filedNam…...

【C#】静默安装、SQL SERVER静默安装等

可以通过cmd命令行来执行&#xff0c;也可以通过代码来执行&#xff0c;一般都需要管理员权限运行 代码 /// <summary>/// 静默安装/// </summary>/// <param name"fileName">安装文件路径</param>/// <param name"arguments"…...

在vue3中定义组件的5种方式

在vue3中定义组件的5种方式 Vue 正在不断发展&#xff0c;目前在 Vue3 中定义组件的方法有多种。从选项式到组合式再到类API&#xff0c;情况截然不同。本文将会定义一个简单的组件并使用所有可用的方法重构它。 选项式 这是在 Vue 中声明组件的最常见方法。从 Vue1 就开始存…...

算法训练营题目,忘了第几天了

144. 二叉树的前序遍历 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3] var res[]int func preorderTraversal(root *TreeNode) []int {res []int{}traval(root)return res }func traval(no…...

蓝桥杯-统计子矩阵

统计子矩阵 题目链接 思路&#xff1a; 使用前缀和滑动窗口 &#xff0c;可以先计算出纵向或横向的前缀和&#xff0c;matrix[i][j]表示前i行第j列之和 然后遍历上边界top和下边界buttom&#xff0c;再这个上下边界内使用滑动窗口&#xff0c;由于前面维护了纵向前缀和&…...

在线预览Word、Excel、PowerPoint等文件

在我们工作时&#xff0c;经常会有在线查看各种不同类型的文件的需要&#xff0c;如Word文档、Excel表格、PowerPoint幻灯片和PDF等。可以直接在这里预览&#xff1a;https://www.compdf.com/webviewer/demo Word 文件实现前端预览 方案一&#xff1a; 使用 XDOC 可以实现预…...

准确预测极端降水,哥伦比亚大学推出升级版神经网络 Org-NN

内容一览&#xff1a;随着环境变化加剧&#xff0c;近年来全球极端天气现象频频出现&#xff0c;准确预测降水强度对人类以及自然环境都十分重要。传统模型预测降水的方差较小&#xff0c;偏向小雨&#xff0c;对极端降水预测不足。 关键词&#xff1a;极端天气 内隐学习 神经网…...

【数据结构】反转链表、链表的中间节点、链表的回文结构(单链表OJ题)

正如标题所说&#xff0c;本文会图文详细解析三道单链表OJ题&#xff0c;分别为&#xff1a; 反转链表 &#xff08;简单&#xff09; 链表的中间节点 &#xff08;简单&#xff09; 链表的回文结构 &#xff08;较难&#xff09; 把他们放在一起讲的原因是&#xff1a; 反转链…...

Python爬虫-抓取的目标数据为#x开头,怎么解决?

前言 本文是该专栏的第4篇,后面会持续分享python爬虫案例干货,记得关注。 在做爬虫项目的时候,有时候抓取的平台目标数据为&#x开头,如下图所示: 浏览器显示的正常数据,但通过爬虫协议获取到的网页源码数据却是以&#x开头的隐藏数据,遇到这种情况,爬虫需要怎么处…...

短视频账号矩阵系统/技术开发搭建私有部署

本系统是基于短视频领域的新一代系统&#xff0c;旨在提供一个高效、全面的短视频管理与分发平台。系统采用先进的开发算法和技术&#xff0c;实现了智能化视频分类、推荐和用户互动功能。 目录 一、抖音SEO账号矩阵系统的开发和部署遵循以下原则&#xff1a; 二、账号矩阵绑…...

光致发光二极管光源——荧光效率检测系统

发光二极管&#xff08;LED&#xff09;光源已经逐步地取代传统光源&#xff0c;并在生产和生活中得以广泛应用。荧光粉在LED照明设备中起到了至关重要的作用&#xff0c;其功能为将转换芯片所产生的紫外或者蓝光&#xff0c;发射出目标颜色的光。近年来&#xff0c;人们为了提…...

【手撕C语言】多线程

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言,Linux基础,ARM开发板&#xff0c;软件配置等领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff01;送给自己和读者的一句鸡汤&#x1f914;&…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

redis和redission的区别

Redis 和 Redisson 是两个密切相关但又本质不同的技术&#xff0c;它们扮演着完全不同的角色&#xff1a; Redis: 内存数据库/数据结构存储 本质&#xff1a; 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能&#xff1a; 提供丰…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...