TypeScript(二):TypeScript的细节

news2024/11/26 13:33:21

TypeScript语法细节

联合类型(满足其中一个即可)

  • 可以使用多种运算符,从现有的类型中构建新类型
    • const number|string = 123
  • 可以是这些类型中的任何值
  • 但是使用的时候需要小心
let virable: number | string = 123

function getData(id: number | string) {
    //若我们想使用length方法,需要使用类型缩小
    //直接使用会报错
    // console.log(id.length)
    if (typeof id === "string") {
        console.log(id.length)
    } else {
        console.log(id);
    }
}

类型别名

  • TypeScript中我们可以给类型起别名
  • 主要是方便代码的阅读以及联合类型的复用
type IDtype = number | string

function getData(id:IDtype) {
    //若我们想使用length方法,需要使用类型缩小
    //直接使用会报错
    // console.log(id.length)
    if (typeof id === "string") {
        console.log(id.length)
    } else {
        console.log(id);
    }
}

接口声明

  • TypeScript中可以使用interface,对对象类型进行取别名
//采用声明式命名
interface IPerson {
    name: string,
    age:number
}
  • 在大部分情况下,type与interface是没有区别的,实现的功能是一样的

type与interface的区别

  • 一是type可以对应多种类型,而interface只能针对于对象类型
  • 二是type不能对同一别名重复声明,而interface可以
    • interface重复声明一个别名,可以将其进行合并
  • 三是interface具有继承性,方便了代码后期的拓展
// * 一是type可以对应多种类型,而interface只能针对于对象类型
type numberType = number
type ObjType = { x: string }
interface IObj { x: string }

// * 二是type不能对同一别名重复声明,而interface可以
//   * interface重复声明一个别名,可以将其进行合并
interface IObj { y: number }//需要满足x以及y

// * 三是interface具有继承性,方便了代码后期的拓展
interface IObjZ extends IObj {
    //需要满足x以及y
    z:boolean
}
  • 总结,在实际开发中,对象类型使用interface,其他类型使用type即可

交叉类型(多种类型要同时满足)

  • 通常是针对于对象类型进行的
  • 若是普通类型的使用交叉类型,则会自动推断出是never类型
type myType = number & string
//通常不会这样操作
  • 现在有两个对象类型,需要同时满足
interface IObj1 {
    name: string
    age:number
}

interface IObj2{
    walk:()=>void
}

type IObj1IObj2 = IObj1&IObj2
//类型注解的时候可以使用IObj1IObj2,与下面的代码一致
const myObj: IObj1 & IObj2 = {
    name: "zhangcheng",
    age: 18,
    walk() {
        console.log("walk");
    }
}

类型断言as

  • 通常用在获取元素节点的时候

  • 获取元素节点的时候,若根据标签获取 TS会根据标签推断出生成的是什么类型,可以做后续操作

  • 但是若使用 id或者class进行获取,则不会推断出是什么类型,后续的操作也不能正常进行

const imEle = document.querySelector("div")
//可以直接进行对应类型的操作

image.png

const imEle = document.querySelector(".myDiv")
//可以进行指定
const imEle = document.querySelector(".myDiv") as HTMLDivElement

image.png

image.png

  • 对于普通类型的也可以进行类型断言
    • 一般是由确定的类型转成不太确定的类型
    • 或者由宽泛的类型,转成确定的类型
    • 注意不能对类型强制类型转换
let str: string = "123" as any

let myAny:any = 123 as number

非空类型断言

  • 对标识符后面加!进行非空类型断言
  • 在上述的学习中,我们知道,有些标识符是可有可无的
  • 对于可有可无的标识符,我们在确保一定存在的情况下,就可以使用非空类型断言
function foo(message?: string) {
    //直接使用会报错,因为message有可能没有
    // console.log(message.length);

    //解决方案一,使用可选链
    console.log(message?.length)

    //解决方案二:非空类型断言,在message一定存在的情况下
    console.log(message!.length)
}

字面量类型

  • 当我们使用const声明一个变量的时候,会用后面的值当作一个类型,即为 字面量类型

image.png

  • 但是单纯的这样写字面量类型,是没有意义的
  • 通常用于 类似于枚举的用途
type requestType = "GET" | "POST"

function request(url: string, method: requestType) {
    //这样method只能取GET或者POST
}

request("http://xxx","GET")
  • 但是若是以下情况,则不能直接传值
    • 我们将要传入的信息用对象包裹
type requestType = "GET" | "POST"

function request(url: string, method: requestType) {
    //这样method只能取GET或者POST
}

let info = {
    url: "http://xxxx",
    method:"GET"
}
//这样直接传会报错,因为info.method是string类型,而函数参数是requestType类型
// request(info.url,info.method)

//解决方案一
//使用类型断言
request(info.url, info.method as "GET")

//解决方案二
//使用字面量推理
let info2 = {
    url: "http://xxxx",//url的类型"http://xxxx"
    method:"GET"//method的类型"GET"
} as const

request(info2.url,info2.method)

类型缩小

  • 目的是让一个类型,缩小到一个更加准确的范围
  • 而与类型缩小一同使用的就是 类型保护
  • 类型保护的方法通常有以下方法
    • typeof
    • === !==
    • instanceof
    • in
//typeof
type messageType = string | number
function getDataId(id: messageType) {
    //id有可能是string类型或者,number类型
    if (typeof id === "string") {
        //判断条件就是类型保护,只有在string类型状态下,才会做如下操作
        console.log(id.split(" "))
    }
}

//===/!==通常用在判断字面量类型上
type requestType = "GET" | "POST"

function request(method: requestType) {
    //method有可能是GET或者POST
    if (method === "GET") {
        //当method为GET的时候,执行的操作
    } else {
        
    }
}

//instanceof
function formate(date: string | Date) {
    //时间的格式化,用于可能传入string或者Date对象
    if (date instanceof Date) {
        //判断date是否是Date实例出来的
    }
}

//in,通常用于判断传入的对象中有没有某个属性
type userInfoType = {name:string,age:number}
let userInfo:userInfoType = { name: "zhangcheng", age: 18 }
function changeUserInfo(userInfo:userInfoType) {
    //判断userInfo中是否有name属性
    if ("name" in userInfo) {
        console.log(userInfo.name);
    }
}

TypeScript函数的类型

  • TypeScript中,函数参数有类型,函数的返回值有类型
  • 而函数本身也有类型
  • 通过函数类型表达式进行声明
//type fnType = (参数:参数类型)=>返回值类型
type fnType = (num1: number,num2:number) => number

//在一个函数中传入另外一个函数
//对这个函数进行类型指定
function numberSum(fn: fnType) {
    console.log(fn(10,20)) 
}

numberSum(function (num,num1) {
    return num+num1
})
  • 通过函数调用签名的方式进行声明
    • 因为函数本身是一个对象
    • 若想将函数作为一个对象,且使用其中的属性,就可以使用调用签名的方法
interface Ifn {
    name: string
    age: number
    //以下就是函数调用签名,代表这个对象可以被调用
    (num1:number,num2:number):number
}

function calc(fn: Ifn) {
    console.log(fn.name,fn.age);
    fn(10,20)
}

function sum(num1:number,num2:number) {
    return num1+num2
}
sum.name = "123"
sum.age = 18

calc(sum)
  • 构造签名
    • 是指函数可以通过 new方法进行调用
class Person{

}

interface ICONPerson {
    //构造签名
    new () : Person
}

function factory(fn: ICONPerson) {
    return new fn()
}

参数的可选类型

  • 在函数的参数中,有些参数是可以传可以不传的,那么我们可以将这个参数设置为可选参数
  • 参数设置为可选参数,其类型就是 指定的类型 | undefined的联合类型
  • 其中y就是可选类型
  • 一般可选类型都是设置在最后
function sum(x:number,y?:number){}

参数的默认值

  • 我们可以给函数的参数设置默认值
  • 设置默认值的参数,在实际调用中,可以不用传参
  • 设置默认值的参数,可以不用标明类型注解
  • 同时该参数可以接收 undefined
function sum(x:number,y=100){}

剩余参数

  • 我们可以使用…的方式接收传递进来的剩余参数
function sum(...arr: (string | number)[]) {
    console.log(arr);
}

函数的重载(了解)

  • 现在有一个需求
    • 有一个sum函数,接收两个参数
    • 这两个参数可能是number类型或者string类型
    • 返回两个参数相加的值
  • 注意:联合类型是不能使用+运算符的
//函数重载
function sum(num1: number, num2: number)
function sum(num1:string,num2:string)

//通用函数,是不能直接被调用的
function sum(num1, num2) {
    return num1+num2
}

console.log(sum(10, 20));
console.log(sum("10", "20"));
//会报错
// console.log(sum(10,"20"));

可推导的this类型

  • 目前在vue3以及react的项目中,其实很少再用到this了
  • 但是我们还是应该了解以下this的类型
  • 在没有特殊配置的情况下,TS中的this类型就是any类型
let obj = {
    name: "zhangcheng",
    sport() {
        console.log(this);
    }
}

function sum() {
    console.log(this);
}
  • 我们可以通过 tsc --init初始化TS的配置,会生成一个 tsconfig.json的文件

  • noImplicitThis配置项为true,将不会允许模糊的this出现

    • 但是this会通过上下文进行推导,推导成功的则正常使用(对象obj中的this
    • 没有推导成功的,则编译不通过(sum函数中的this
  • 同时,我们可以给 sum函数指定this

//第一个参数为指定this类型的参数,这是固定位置,且名称不能变
//后续的参数才是参数
function sum(this:{name:string},arg:number) {
    console.log(this);
}

//只能通过call,bind,apply调用
sum.call({name:"zhangcheng"},10)

this相关的内置工具

  • ThisParameterType和OmitThisParameter
function sum(this: { name: string }, num: number) { }

//提取函数中的this类型
type sumThis = ThisParameterType<typeof sum>

//剔除this,其余参数的类型
type argType = OmitThisParameter<typeof sum>
  • ThisType工具,主要是将上下文的this绑定到某一个类型身上
    • pinia内部实际上用了这个方法,这只是一个简易版本,运行将会是undefined
interface IState{
    stateName:string
}

interface IStore {
    state: IState
    getData:()=>void
}

//这里的this类型,将会是IState类型
let store: IStore & ThisType<IState> = {
    state: { stateName: "lisi" },
    getData() {
        //因此可以直接通过this.stateName访问state中的变量
        console.log(this.stateName);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1456795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

金山WPS下的word,如何删除表格下面的大段空白

在csdn&#xff0c;你甚至可以学习到wps小技巧。 如题&#xff0c;这种大段空白怎么设置文本格式&#xff0c;表格格式都没用。正常的backspace删除也没用。 解决方式如下&#xff1a; 长按鼠标左键拖拽选中空白区域&#xff08;可能没有选中成功的特效没关系&#xff09;&am…

Golang - 使用CentOS 7 安装Golang环境

文章目录 操作步骤 操作步骤 为在CentOS 7上安装Go语言环境&#xff0c;可以按照以下步骤进行操作&#xff1a; 下载Go语言包&#xff1a; 从官方网站 https://golang.org/dl/ 下载适用于Linux的Go语言包。 解压缩Go语言包&#xff1a; 使用以下命令解压缩下载的Go语言包 […

洛谷 P6546 [COCI2010-2011#2] PUŽ

讲解&#xff1a; 首先还是正常输入&#xff1a; int a,b,v; cin>>a>>b>>v; 然后经入一个函数num&#xff1a; cout<<num(1.0*(v-a),(a-b))1<<endl; 之所以要乘以1.0是因为要向上取整&#xff01;而这个num函数的两个参数则是“蜗牛白天爬了多…

Asymmetric Temperature Scaling(NeurIPS 2022)论文速读

paper&#xff1a;Asymmetric Temperature Scaling Makes Larger Networks Teach Well Again official implementation&#xff1a;https://gitee.com/mindspore/models/tree/master/research/cv/ats 本文的创新点 在知识蒸馏中&#xff0c;一个奇怪的现象是大的教师模型未必…

网络原理(5)--HTTPS是如何进行加密的

&#x1f495;"Echo"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;网络原理(5)–HTTPS是如何进行加密的 在网络原理(4)中介绍了HTTP协议的相关内容,HTTP协议在传输的过程中存在着安全问题,实际上现在的网络中基本不再使用HTTP,而是使用一种更加安…

记录setData报错TypeError: [object Array] is not a function

小程序调用setData控制台显示报错.但是功能正常 同样的各个地方调setData都报错,经过一轮排除法后发现是自定义组件写法有问题 修改正确之后就没问题了

穷人沉迷多巴胺,富人追求内啡肽

奶头乐理论 1995年&#xff0c;美国旧金山召开了一场由500位富豪和政治家组成的精英会议。 会议认为&#xff0c;全球化的发展将使贫富差距迅速拉大、阶层矛盾日益激烈。 如何让穷人安分守己&#xff1f;他们想出了一个办法&#xff1a; 只需要像喂婴儿奶嘴一样&#xff0c…

服务运行时动态挂载JavaAgent和插件——Sermant热插拔能力解析

作者&#xff1a;华为云高级软件工程师 栾文飞 一、概述 Sermant是基于Java字节码增强技术的无代理服务网格&#xff0c;其利用Java字节码增强技术&#xff0c;为宿主应用程序提供服务治理功能&#xff0c;以解决大规模微服务场景中的服务治理问题&#xff0c;通过Java字节码…

uniapp H5唤起手机App 中间下载页

我这里直接是打开中间下载页&#xff0c;在下载页判断手机是否已存在App&#xff0c;有则唤起App&#xff0c;没有则可点击下载按钮下载app。 唤起App的关键语句是&#xff1a;window.location.href scheme Scheme链接格式样式&#xff1a; [scheme]://[host]/[path]?[que…

Backend - Django SimpleUI(美化 Django Admin )

目录 一、作用 二、安装 & 配置 &#xff08;一&#xff09;安装依赖 &#xff08;二&#xff09;配置 &#xff08;三&#xff09;运行 三、基础设定 &#xff08;一&#xff09;创建用户 &#xff08;二&#xff09;设置标题 &#xff08;三&#xff09;设置登录…

算法刷题:找到字符串中所有的字母异位词

找到字符串中所有的字母异位词 .题目链接题目详情题目解析算法原理滑动窗口流程图定义指针及变量进窗口判断出窗口更新结果 我的答案 . 题目链接 找到字符串中所有的字母异位词 题目详情 题目解析 所谓的异位词,就是一个单词中的字母,打乱顺序,重新排列得到的单词 如:abc-&g…

爬虫入门一

文章目录 一、什么是爬虫&#xff1f;二、爬虫基本流程三、requests模块介绍四、requests模块发送Get请求五、Get请求携带参数六、携带请求头七、发送post请求八、携带cookie方式一&#xff1a;放在请求头中方式二&#xff1a;放在cookie参数中 九、post请求携带参数十、模拟登…

使用IDEA配置GO的开发环境备忘录

1. 安装GO 1.1 下载&安装 进入GO的官网下载对应的GO&#xff0c;本人环境为mac选择最新的1.22.0版本&#xff0c;在本地安装即可 1.2 配置相关环境变量 修改~/.bash_profile&#xff0c;添加如下的配置 GOPATH/Users/kevin/go/src GOBIN/Users/kevin/go/go/bin GOROOT/…

【Redis快速入门】深入解读哨兵模式

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

贪心算法之合并区间

“任世界多宽广&#xff0c;停泊在这港口~” 区间问题&#xff0c;涉及到最多的就是 取交集 和 并集的概念。我们使用C排序算法后&#xff0c;其默认规则就是按照 “左排序”进行的。因而&#xff0c;我们实质上注意的是每一个区间的 右端点&#xff0c;根据题目要求&#xff…

如何使用Docker部署Drupal并结合cpolar实现固定公网地址访问

文章目录 前言1. Docker安装Drupal2. 本地局域网访问3 . Linux 安装cpolar4. 配置Drupal公网访问地址5. 公网远程访问Drupal6. 固定Drupal 公网地址 前言 Dupal是一个强大的CMS&#xff0c;适用于各种不同的网站项目&#xff0c;从小型个人博客到大型企业级门户网站。它的学习…

C++ Webserver从零开始:配置环境(九)——下载github的项目进行测试

前言 大家好&#xff0c;我又来更新Webserver的博客了。上一次更新这个专栏时2024.2.5号&#xff0c;离现在已经13天了。非常抱歉&#xff0c;中间隔了那么久。一方面是基础知识学完之后&#xff0c;就要开始自己写代码了。看基础知识和写代码是两回事&#xff0c;理论和实践的…

Python Selenium实现自动化测试及Chrome驱动使用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站零基础入门的AI学习网站~。 目录 ​编辑 前言 Selenium简介 安装Selenium库 编写自动化测试脚本 1 打开浏览器并访问网页 2 查找页面元…

如何低成本实现商场室内导航地图制作

商场地图导航可提升顾客服务体验&#xff0c;促进商场信息化建设。蜂鸟视图提供两种低成本的商场导航实现方式&#xff0c;以满足不同需求。 一、模拟导航 用户可选用“模拟导航”&#xff1a;将商场CAD图纸导入蜂鸟视图地图编辑器&#xff0c;通过简单操作生成室内3D地图&…