【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

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

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

相关文章

mysql安装包怎么打不开_mysql安装打不开怎么办

mysql安装打不开的解决办法&#xff1a;首先右键单击“计算机”&#xff1b;然后在弹出的“系统属性”界面中&#xff0c;单击“环境变量”&#xff1b;接着选中path&#xff0c;并在path中加入mysql的安装路径&#xff1b;最后“确定”保存即可。 添加mysql安装路径。 首先右键…

电脑无法查看计算机属性,我的电脑属性打不开怎么办

我的电脑属性打不开怎么办 我们在对电脑进行一些设置或者我们要查看电脑的设置,我们都可以从我的电脑属性中查看。那么我的电脑属性打不开怎么办呢?下面就让小编为大家介绍一下我的电脑属性打不开的.解决办法吧,希望大家认真学习。 1,第一步,在“开始”菜单中打开“运行”…

汉字无法进入计算机,电脑不能打汉字怎么办

有时候在打字聊天的时候突然发现&#xff0c;电脑的输入法出现了问题&#xff0c;无法输入文字了&#xff0c;怎么办。下面学习啦小编给大家讲解一下关于电脑不能打汉字的解决方法&#xff0c;希望大家喜欢! 电脑不能打汉字的解决方法 【关闭高级文字服务】 1&#xff0c;首先我…

golang(Gin模板与渲染)中相对路径找不到文件filepath.Join()

使用os.Getwd()获取文件路径以及**filepath.Join()**解决相对路径访问问题 使用gin来渲染模板时&#xff0c;一直找不到指定路径下的模板文件&#xff0c;使用绝对路径可以输出&#xff0c;但是相对路径就会出现问题。后来发现应该是go mod运行时的路径不是原本所在的路径&…

mysql启动报错:Cant start server cant check PID filepath No such file or directory

问题显现&#xff1a;问题排查1.象通过 systemctl status mysqld.service 命令查看状态现在是未启动成功 正在启动中 2.查看mysql启动日志 cat /var/log/mysqld.log 提示报错&#xff1a;Can’t start server: can’t check PID filepath: No such file or directory 错误原…

KeyError: ‘Failed to format this callback filepath:~~~. Reason: \‘val_loss\‘

软件环境&#xff1a; Keras 2.1.6 Tensorflow 2.3 今天在使用keras训练分类模型的时候&#xff0c;因为使用了格式化命名模型文件&#xff0c;出现如题报错&#xff0c;经过查询&#xff0c;发现网上的解决方案是说因为版本更新的原因目前使用的不再是val_acc而是val_accuracy…

小程序 writeFile参数filePath要怎么写

// 在本地用户文件目录下创建一个文件 hello.txt&#xff0c;写入内容 "hello, world" const fs wx.getFileSystemManager() fs.writeFileSync(${wx.env.USER_DATA_PATH}/hello.txt, hello, world, utf8)// 写入图片 fsm.writeFile({filePath:${wx.env.USER_DATA_PA…

umi中AssertionError [ERR_ASSERTION]: filePath not found of

看到了吗&#xff0c;兄弟姐妹们。 这个问题整了一天才整的出来 错误的原因主要是由于npm安装的依赖和yarn安装的依赖起了冲突 如果是使用npm i 进行安装的依赖&#xff0c;在使用yarn start进行启动的时候就会出现这个问题 解决办法 1 不知道冲突的是哪个第三方包 删除原…

今天我花了一个通宵的时间安装Windows11系统居然失败,忍不住哭了!

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…

UDP服务器—实现数据通信

目录 前言 1.接口介绍 2.编写服务器 3.编写客户端 4.测试 总结 前言 在这篇文章中为大家介绍如何通过编码实现数据通信&#xff0c;实现思路是根据前面介绍的网络编程函数编写一个服务端和客户端&#xff0c;实现客户端和服务端双方通信 1.接口介绍 创建套接字 #include…

【TypeScript】this指向,this内置组件

this类型 TypeScript可推导的this类型函数中this默认类型对象中的函数中的this明确this指向 怎么指定this类型 this相关的内置工具类型转换ThisParameterType<>ThisParameterType<>ThisType TypeScript可推导的this类型 函数中this默认类型 对象中的函数中的this…

光遇android和ios有什么区别,光遇安卓和苹果可以一起玩吗?

01 首先经过测试&#xff0c;国际服的安卓和苹果是可以一起玩的&#xff0c;这两个平台的玩家可以相互添加好友&#xff0c;并且在地图中也可以看到各自的身影。既然国际服才用了互通的规则&#xff0c;那么国服自然也应该互通&#xff0c;但是受到系统兼容等问题的影响&#x…

ios的皇室战争怎么转android,皇室战争苹果怎么转安卓?小问题,让小编来告诉你...

皇室战争苹果怎么转安卓&#xff1f;小问题&#xff0c;让小编来告诉你 皇室战争安卓国服即将上线&#xff0c;许多玩家都满怀期待&#xff0c;不过也有一些疑问&#xff0c;就是皇室战争苹果可以转安卓吗&#xff1f;皇室战争苹果可以和安卓数据互通吗&#xff1f;看这里 皇室…

android转服务器吗,王者荣耀角色迁移iOS区可以转安卓区吗 王者荣耀角色迁移iOS区转安卓区详情...

王者荣耀角色迁移iOS区可以转安卓区吗?王者荣耀在王者营地中推出角色迁移功能&#xff0c;角色迁移上线后不少玩家都在问iOS区可以转安卓区的问题&#xff0c;下面小编带来了王者荣耀角色迁移iOS区转安卓区详情&#xff0c;一起来看看吧。 王者荣耀角色迁移iOS区转安卓区详情 …

ios系统换成android系统 游戏,2020王者荣耀苹果转换安卓系统 王者苹果转换安卓系统怎么转...

2020王者苹果怎么转换安卓系统?王者苹果转换安卓系统怎么转?相信很多IOS玩家都想换成安卓手机&#xff0c;可是却不知道怎么把游戏账号转移到安卓系统上。关于相关的转移操作&#xff0c;就随琵琶网小编来了解一下吧! 2020王者苹果怎么转换安卓系统? 很多IOS都有看到自己身边…

个性闹钟屏保带滚动字幕

基于我的时间工具&#xff08;有数字版和插件版&#xff09;的衍生修改而来 功能&#xff1a; 1&#xff09;滚动字幕可滚动可静止&#xff0c;可自定义文本 颜色 速度等&#xff0c;类似LED电子显示屏 &#xff08;或投影仪投屏使用&#xff09; 2&#xff09;带阴历 阳历 …

自定义屏保

先创建一个form窗体应用&#xff0c;然后在里面放几个文本框&#xff0c; 然后双击这个窗体进入代码页面 开始初始化的代码 隐藏或者显示Label控件&#xff0c;以及要改变的对象 在显示或者预览和屏保前&#xff0c;对所有的控件进行控制 屏保的设置。计算器、背景等

Win10屏保设置位置在哪里可以找到

如果我们感觉自己在离开电脑时&#xff0c;屏幕容易耗电&#xff0c;或者不想被看到屏幕内容&#xff0c;就可以设置屏幕保护&#xff0c;那么win10屏保设置在哪里呢&#xff0c;其实个性化中就能设置。 更多重装系统教程尽在小白系统重装官网 1、首先右键桌面空白处&#xf…

win7计算机锁频图片怎么设置,win7电脑锁屏壁纸怎么设置为个性化图片?

当我们每天使用win7系统电脑时&#xff0c;如果我们暂时离开电脑&#xff0c;系统会自动进入锁屏状态&#xff0c;但是有些用户认为默认的锁屏壁纸太单调&#xff0c;一点都不美观。很多用户想修改锁屏界面壁纸&#xff0c;那么win7电脑锁屏壁纸怎么设置呢&#xff1f;以下小编…

c++11 标准模板(STL)(std::basic_fstream)(五)

定义于头文件 <fstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_fstream : public std::basic_iostream<CharT, Traits> 类模板 basic_fstream 实现基于文件的流上的高层输入/输出。它将 std::basic_i…